2275 lines
75 KiB
Python
Executable file
2275 lines
75 KiB
Python
Executable file
# coding=utf-8
|
|
|
|
from functools import cache
|
|
|
|
import datetime, re
|
|
|
|
|
|
|
|
# Create your views here.
|
|
|
|
# import mx.DateTime
|
|
|
|
from django.contrib import auth
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.mail import send_mail
|
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
|
from django.db.models import *
|
|
from django.http import Http404, HttpResponse, HttpResponseRedirect, JsonResponse
|
|
#from django.newforms import form_for_instance
|
|
from django.shortcuts import *
|
|
# from django.shortcuts import render
|
|
from django.template import RequestContext
|
|
from django.urls import reverse_lazy
|
|
# from django.utils import simplejson
|
|
from django.views.generic import *
|
|
|
|
import django.core.serializers
|
|
|
|
# from cachier import cachier
|
|
from dal import autocomplete
|
|
from datatableview import Datatable, columns, helpers
|
|
from datatableview.views import DatatableView, XEditableDatatableView
|
|
from django_tables2 import SingleTableView
|
|
from rest_framework import generics, viewsets
|
|
|
|
from .forms import *
|
|
from .models import *
|
|
from .serializers import *
|
|
from .tables import *
|
|
|
|
from .common import AddPatient, SortNHI, UpdateNHICase, QueryMS
|
|
|
|
#import ntuhgov.intra as intra
|
|
import ntuhgov.portal
|
|
# import ntuhgov import portal_spynner3 as portal_spynner
|
|
# from ntuhgov import portal_spynner3 as portal
|
|
# from ntuhgov import portal_ghost_xvfb as portal
|
|
from ntuhgov import portal_selenium as portal
|
|
|
|
# from . import kd22
|
|
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# @cache
|
|
# @cachier(next_time=True)
|
|
def top_icd10(q=None):
|
|
# qs = ICD10CMfinal.objects.annotate(count=Count('treatment')).order_by('-count')
|
|
# if q:
|
|
# qs = qs.filter(
|
|
# Q(ICD10CM__istartswith=q)
|
|
# | Q(ICD9CM_code__istartswith=q)
|
|
# | Q(ICD10CM_English__icontains=q)
|
|
# | Q(ICD9CM_English__icontains=q))
|
|
# return qs
|
|
|
|
if q is None:
|
|
return ICD10CMfinal.objects.all().order_by('-icd10count__count')
|
|
return ICD10CMfinal.objects.all()
|
|
return ICD10CMfinal.objects.annotate(count=Count('treatment')).order_by('-count')
|
|
return top_icd10(None).filter(
|
|
Q(ICD10CM__istartswith=q)
|
|
| Q(ICD9CM_code__istartswith=q)
|
|
| Q(ICD10CM_English__icontains=q)
|
|
| Q(ICD9CM_English__icontains=q))
|
|
|
|
@cache
|
|
def top_icd10_list(n):
|
|
return [x.ICD10CM for x in ICD10CMfinal.objects.all().order_by('-icd10count__count')[:n]]
|
|
|
|
|
|
class ICD10Autocomplete(autocomplete.Select2QuerySetView):
|
|
def get_queryset(self):
|
|
# Don't forget to filter out results depending on the visitor !
|
|
if not self.request.user.is_authenticated:
|
|
return ICD10CMfinal.objects.none()
|
|
|
|
# qs = ICD10CMfinal.objects.all()
|
|
qs = top_icd10(self.q)
|
|
|
|
return qs
|
|
|
|
|
|
def top_icd10_list_dict(request):
|
|
# a = top_icd10()
|
|
# print(type(a))
|
|
# for i in a:
|
|
# print(i, type(i))
|
|
# break
|
|
count=10
|
|
# return JsonResponse(list(top_icd10()[:count].values()), safe=False)
|
|
return JsonResponse(list(top_icd10().values()[:count]), safe=False)
|
|
|
|
class CreateForPatient(CreateView):
|
|
# def get_initial(self):
|
|
# patient = get_object_or_404(Patient, pk=self.kwargs.get('patient_id'))
|
|
# return {
|
|
# 'patient': patient,
|
|
# }
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["patient"] = get_object_or_404(Patient, pk=self.kwargs.get('patient_id'))
|
|
return context
|
|
|
|
|
|
class CreateEventForTreatment(CreateView):
|
|
fields = '__all__'
|
|
def get_initial(self):
|
|
treatment = get_object_or_404(Treatment, pk=self.kwargs.get('treatment_id'))
|
|
return {
|
|
'treatment': treatment,
|
|
}
|
|
|
|
|
|
|
|
@login_required
|
|
def patient_add(request):
|
|
if request.method == 'GET':
|
|
parameters = request.GET
|
|
elif request.method == 'POST':
|
|
parameters = request.POST
|
|
|
|
chartno = parameters.get('ChartNo', '')
|
|
name = parameters.get('Name', '')
|
|
idcode = parameters.get('idcode', '')
|
|
force = parameters.get('force', '')
|
|
|
|
# p = AddPatient({'IdNo': idcode, 'ChartNo': chartno,}, force=force)
|
|
|
|
r = portal.QueryModifyPatBase({'IdNo': idcode,
|
|
'ChartNo': chartno,
|
|
})
|
|
|
|
if r:
|
|
r['name'] = r['ChtName']
|
|
r['medical_records'] = r['ChartNo']
|
|
r['gender'] = r['Sex']
|
|
r['birthday'] = r['Birth']
|
|
r['address'] = r['AddressControl1']
|
|
r['phone'] = r['ContTel']
|
|
r['id_cards'] = r['IdNo']
|
|
|
|
result = [r]
|
|
else:
|
|
result = []
|
|
|
|
if force and len(result)>0:
|
|
r=result[0]
|
|
|
|
if r['gender'] == 'M':
|
|
r['gender'] = 1
|
|
else:
|
|
r['gender'] = 2
|
|
# hw = intra.HeightWeight(r['id_cards'])
|
|
# hw = ntuhgov.portal.HeightWeight(r['id_cards'])
|
|
hw = portal.BriefHistoryLink(r['id_cards'])
|
|
p = Patient(name = r['name'],
|
|
medical_records = r['medical_records'],
|
|
gender = r['gender'],
|
|
birthday = r['birthday'],
|
|
address = r['address'],
|
|
phone = r['phone'],
|
|
id_cards = r['id_cards'],
|
|
# height = hw['Height'],
|
|
# weight = hw['weight'],
|
|
)
|
|
|
|
try:
|
|
p.height = int(hw['Height'])
|
|
except:
|
|
pass
|
|
try:
|
|
p.weight = int(hw['Weight'])
|
|
except:
|
|
pass
|
|
p.save()
|
|
return HttpResponseRedirect('/patient/detail/%d/' % p.id)
|
|
|
|
form = PatientForm()
|
|
return render(request, 'ck/patient_add.html',
|
|
{
|
|
'form': form,
|
|
'result': result,
|
|
}
|
|
)
|
|
return render_to_response('ck/patient_add.html',
|
|
{
|
|
'form': form,
|
|
'result': result,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
@login_required
|
|
def patient_detail(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
if object_id:
|
|
qset = (
|
|
Q(patient=object_id)
|
|
)
|
|
treatments = Treatment.objects.filter(qset).distinct()
|
|
else:
|
|
treatments = []
|
|
|
|
# update patient timestamp
|
|
|
|
# ts = patient.timestamp.date()
|
|
# for treatment in treatments:
|
|
# if treatment.date_completed > ts:
|
|
# ts = treatment.date_completed
|
|
# if patient.timestamp.date() != ts:
|
|
# patient.timestamp = datetime.datetime.combine(ts, patient.timestamp.time())
|
|
# patient.save()
|
|
|
|
pacsimages = PACSImage.objects.filter(Q(patient=object_id),Q(Modality__startswith='CT')|Q(Modality__startswith='MR')).order_by('-ExamDate')
|
|
if len(pacsimages) > 9:
|
|
pacsimages = pacsimages[0:9]
|
|
|
|
# response = render_to_response("ck/patient_detail.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatments": treatments,
|
|
# "pacsimages": pacsimages,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, "ck/patient_detail.html",
|
|
{
|
|
"patient": patient,
|
|
"treatments": treatments,
|
|
"pacsimages": pacsimages,
|
|
}
|
|
)
|
|
response.set_cookie('patient', object_id)
|
|
request.session['patient'] = object_id
|
|
return response
|
|
|
|
@login_required
|
|
def patient_follow(request):
|
|
pass
|
|
|
|
|
|
@login_required
|
|
def patient_print(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
if object_id:
|
|
qset = (
|
|
Q(patient=object_id)
|
|
)
|
|
treatments = Treatment.objects.filter(qset).distinct()
|
|
else:
|
|
treatments = []
|
|
|
|
# update patient timestamp
|
|
|
|
# ts = patient.timestamp.date()
|
|
# for treatment in treatments:
|
|
# if treatment.date_completed > ts:
|
|
# ts = treatment.date_completed
|
|
# if patient.timestamp.date() != ts:
|
|
# patient.timestamp = datetime.datetime.combine(ts, patient.timestamp.time())
|
|
# patient.save()
|
|
|
|
# response = render_to_response("ck/patient_print.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatments": treatments,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, "ck/patient_print.html",
|
|
{
|
|
"patient": patient,
|
|
"treatments": treatments,
|
|
}
|
|
)
|
|
response.set_cookie('patient', object_id)
|
|
request.session['patient'] = object_id
|
|
return response
|
|
|
|
|
|
@login_required
|
|
def patient_search(request):
|
|
query = request.GET.get('q', '')
|
|
if query:
|
|
qset = (
|
|
Q(medical_records__icontains=query) |
|
|
Q(name__icontains=query) |
|
|
Q(id_cards__iexact=query)
|
|
)
|
|
results = Patient.objects.filter(qset).distinct()
|
|
if len(results) == 0:
|
|
if re.match('^\d+', query):
|
|
return HttpResponseRedirect('/patient/add/?ChartNo='+query)
|
|
elif re.match('^\w\d+', query):
|
|
return HttpResponseRedirect('/patient/add/?idcode='+query)
|
|
else:
|
|
return HttpResponseRedirect('/patient/add/?Name='+query)
|
|
else:
|
|
results = []
|
|
# print "query=", query
|
|
# print "results=", results
|
|
return render(request, 'ck/patient_search.html',
|
|
{
|
|
"results": results,
|
|
"query": query,
|
|
}
|
|
)
|
|
return render_to_response("ck/patient_search.html",
|
|
{
|
|
"results": results,
|
|
"query": query,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
class PatientDatatableView(XEditableDatatableView):
|
|
model = Patient
|
|
|
|
class datatable_class(Datatable):
|
|
|
|
gender_display = columns.TextColumn ('Gender1', sources=['get_gender_display'])
|
|
|
|
detail = columns.DisplayColumn('Detail' , processor='ProcessDetail')
|
|
operations = columns.DisplayColumn('Operations', processor='ProcessOperations')
|
|
|
|
def ProcessDetail(self, *args, **kwargs):
|
|
data = args[0]
|
|
return f'''
|
|
<a href="{reverse('patient-detail', kwargs={'object_id': data.id})}"><span class="material-icons-outlined">launch</span></a>
|
|
'''
|
|
|
|
def ProcessOperations(self, *args, **kwargs):
|
|
data = args[0]
|
|
# print(data)
|
|
# default_value = kwargs['default_value']
|
|
return f'''
|
|
<a href="{reverse('patient-update', kwargs={'pk': data.id})}"><span class="material-icons-outlined">edit</span></a>
|
|
<a href="{reverse('patient-delete', kwargs={'pk': data.id})}"><span class="material-icons-outlined">delete</span></a>
|
|
'''
|
|
|
|
class Meta:
|
|
ordering = ['-id']
|
|
|
|
columns = [
|
|
'detail',
|
|
|
|
'id',
|
|
'name',
|
|
'medical_records',
|
|
'gender_display',
|
|
'birthday',
|
|
# 'address',
|
|
'phone',
|
|
'id_cards',
|
|
'memo',
|
|
'dead',
|
|
|
|
'operations',
|
|
]
|
|
|
|
processors = {
|
|
'memo': helpers.make_xeditable(),
|
|
}
|
|
|
|
# django-tables2
|
|
# class PatientListView(ListView):
|
|
class PatientListView(SingleTableView):
|
|
model = Patient
|
|
table_class = PatientTable
|
|
# template_name = 'tutorial/people.html'
|
|
|
|
# django-rest-framework-datatables
|
|
class PatientViewSet(viewsets.ModelViewSet):
|
|
queryset = Patient.objects.all().order_by('name')
|
|
serializer_class = PatientSerializer
|
|
|
|
|
|
|
|
@login_required
|
|
def prior_oncrt_query(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
priors = patient.priortreatment_set;
|
|
|
|
answers = intra.oncrt_query(patient.medical_records)
|
|
|
|
# return HttpResponse(str(answers))
|
|
|
|
for answer in answers:
|
|
if answer['way'] != 'Radiosurgery' and not priors.filter(date=answer['start_date']):
|
|
p = PriorTreatment(
|
|
patient = patient,
|
|
date = answer['start_date'],
|
|
treatment = 3,
|
|
period = 1,
|
|
dose = answer['total_dose'],
|
|
memo = answer['site'] + ' ' + answer['remarks'],
|
|
)
|
|
p.save()
|
|
return HttpResponseRedirect('/patient/detail/'+object_id)
|
|
|
|
|
|
@login_required
|
|
def prior_op_note(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
priors = patient.priortreatment_set;
|
|
|
|
# answers = intra.op_note_case(patient.medical_records)
|
|
answers = ntuhgov.portal.op_note_case(patient.medical_records)
|
|
|
|
# return HttpResponse(str(answers))
|
|
|
|
for answer in answers:
|
|
if not priors.filter(date=answer['surgery_date_time']):
|
|
p = PriorTreatment(
|
|
patient = patient,
|
|
date = answer['surgery_date_time'],
|
|
treatment = 1,
|
|
memo = ' '.join([answer['division'], answer['name_surgery'], answer['surgeon']])
|
|
)
|
|
p.save()
|
|
return HttpResponseRedirect('/patient/detail/'+object_id)
|
|
|
|
@login_required
|
|
def prior_path_exam(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
pathexams = patient.pathexam_set;
|
|
|
|
# answers = intra.path_exam(patient.medical_records)
|
|
import ntuhgov.xportal
|
|
answers = ntuhgov.xportal.ReportPathology(patient.medical_records)
|
|
|
|
# return HttpResponse(str(answers))
|
|
|
|
for answer in answers:
|
|
if not pathexams.filter(path_code=answer['PathCode']):
|
|
p = PathExam(
|
|
patient = patient,
|
|
path_code = answer['PathCode'],
|
|
specimen_code = answer['SpecimenCode'],
|
|
specimen_get_date = answer['SpecimenGetDate'][:10].replace('/','-'),
|
|
report_date = answer['ReportDate'][:10].replace('/','-'),
|
|
division = answer['DepCode'],
|
|
bed = answer['WardNoRoomCoBedNo'],
|
|
report = answer['Result'],
|
|
)
|
|
|
|
p.save()
|
|
return HttpResponseRedirect('/patient/detail/'+object_id)
|
|
|
|
@login_required
|
|
def query_height_weight(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('patient')
|
|
patient = Patient.objects.get(id=object_id)
|
|
# hw = intra.HeightWeight(patient.id_cards)
|
|
hw = ntuhgov.portal.HeightWeight(patient.id_cards)
|
|
patient.height = hw['Height']
|
|
patient.weight = hw['Weight']
|
|
patient.save()
|
|
|
|
return HttpResponseRedirect('/patient/detail/'+object_id)
|
|
|
|
|
|
@login_required
|
|
def record_weekly(request, date):
|
|
if not date:
|
|
date = mx.DateTime.today()
|
|
|
|
Monday = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-6,weekday=(mx.DateTime.Monday,0))
|
|
NextMonday = Monday + mx.DateTime.RelativeDateTime(days=+7)
|
|
prevweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-7)
|
|
nextweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+7)
|
|
|
|
weekday = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
|
|
|
|
weekdate = {}
|
|
d = Monday
|
|
for day in weekday:
|
|
weekdate[day] = d.strftime('%m/%d')
|
|
d = d + mx.DateTime.RelativeDateTime(days=+1)
|
|
|
|
# print NextMonday, NNMonday
|
|
sMonday = str(Monday)
|
|
sNextMonday = str(NextMonday)
|
|
qset1 = Q(DTSTART__range=(sMonday, sNextMonday))
|
|
|
|
qset2 = Q(mode__exact=310) #310: 治療
|
|
|
|
events = VEVENT.objects.filter(qset1, qset2).order_by('DTSTART')
|
|
|
|
tids = []
|
|
|
|
for event in events:
|
|
tid = event.treatment.id
|
|
if not tid in tids:
|
|
tids.append(tid)
|
|
|
|
treatments = []
|
|
for tid in tids:
|
|
t = Treatment.objects.get(id=tid);
|
|
treatment = {
|
|
'id': t.id,
|
|
'icd9': t.icd9,
|
|
'other_diagnosis': t.other_diagnosis,
|
|
'accounting': t.get_accounting_display(),
|
|
'dates': [],
|
|
'surgeon': t.surgeon,
|
|
'oncologist': t.oncologist,
|
|
'referral': t.referral,
|
|
}
|
|
|
|
for event in events:
|
|
if tid == event.treatment.id:
|
|
treatment['dates'].append(event.DTSTART.date())
|
|
|
|
# for lesion in Treatment.objects.get(id=tid).lesion_set:
|
|
# treatment.
|
|
|
|
|
|
treatments.append(treatment)
|
|
|
|
|
|
|
|
# treatments = Treatment.objects.filter(id__in=tids)
|
|
|
|
# response = render_to_response("ck/record_weekly.html",
|
|
# {
|
|
# "prevweek": prevweek.date,
|
|
# "nextweek": nextweek.date,
|
|
# "weeknumber": Monday.strftime('%G年 第%V週'),
|
|
# "weekdate": weekdate,
|
|
# "events": events,
|
|
# "treatments": treatments,
|
|
# }, context_instance=RequestContext(request))
|
|
|
|
return render(request, 'ck/record_weekly.html',
|
|
{
|
|
"prevweek": prevweek.date,
|
|
"nextweek": nextweek.date,
|
|
"weeknumber": Monday.strftime('%G年 第%V週'),
|
|
"weekdate": weekdate,
|
|
"events": events,
|
|
"treatments": treatments,
|
|
}
|
|
)
|
|
# return response
|
|
|
|
|
|
@login_required
|
|
def timetable_scheduling(request, date):
|
|
if not date:
|
|
date = mx.DateTime.today()
|
|
|
|
Monday = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+6,weekday=(mx.DateTime.Monday,0))
|
|
NextMonday = Monday + mx.DateTime.RelativeDateTime(days=+7)
|
|
prevweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-7)
|
|
nextweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+7)
|
|
# print NextMonday, NNMonday
|
|
sMonday = str(Monday)
|
|
sNextMonday = str(NextMonday)
|
|
qset = (
|
|
Q(DTSTART__range=(sMonday, sNextMonday))
|
|
)
|
|
|
|
treatments = Treatment.objects.filter(output__id__lt=900)
|
|
|
|
weekday = ['mon', 'tue', 'wed', 'thu', 'fri']
|
|
|
|
weekdate = {}
|
|
d = Monday
|
|
for day in weekday:
|
|
weekdate[day] = d.strftime('%m/%d')
|
|
d = d + mx.DateTime.RelativeDateTime(days=+1)
|
|
|
|
timetable = []
|
|
for treatment in treatments:
|
|
if treatment.vevent_set.filter(qset):
|
|
r = {}
|
|
patient = treatment.patient
|
|
r['name'] = patient.name
|
|
r['medical_records'] = patient.medical_records
|
|
r['indications'] = str(treatment.surgeon) + '\n' + str(treatment.oncologist)
|
|
r['diagnosis_site'] = treatment.other_diagnosis
|
|
r['number'] = ''
|
|
r['node'] = ''
|
|
r['mode'] = ''
|
|
r['time'] = ''
|
|
r['actual_treatment'] = ''
|
|
for day in weekday:
|
|
r[day] = ''
|
|
for event in treatment.vevent_set.order_by('DTSTART'):
|
|
wd = (event.DTSTART.date() - datetime.datetime.fromtimestamp(Monday).date()).days
|
|
if wd in range(0, 6):
|
|
r[weekday[wd]] += event.DTSTART.strftime('%H:%M') + ' ' + event.get_mode_display() + '\n'
|
|
timetable.append(r)
|
|
|
|
|
|
# print timetable
|
|
|
|
# response = render_to_response("ck/timetable_scheduling.html",
|
|
# {
|
|
# "prevweek": prevweek.date,
|
|
# "nextweek": nextweek.date,
|
|
# "timetable": timetable,
|
|
# "weekdate": weekdate,
|
|
# }, context_instance=RequestContext(request))
|
|
return render(request, 'ck/timetable_scheduling.html',
|
|
{
|
|
"prevweek": prevweek.date,
|
|
"nextweek": nextweek.date,
|
|
"timetable": timetable,
|
|
"weekdate": weekdate,
|
|
}
|
|
)
|
|
return response
|
|
|
|
|
|
@login_required
|
|
def treatment_detail(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('treatment')
|
|
treatment = Treatment.objects.get(id=object_id)
|
|
patient = Patient.objects.get(id=treatment.patient_id)
|
|
# response.set_cookie('patient', patient.id)
|
|
request.session['patient'] = patient.id
|
|
if object_id:
|
|
qset = (
|
|
Q(treatment=object_id)
|
|
)
|
|
vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
|
|
lesions = Lesion.objects.filter(qset).distinct()
|
|
else:
|
|
vevents = []
|
|
lesions = []
|
|
|
|
# update treatment date_completed
|
|
|
|
for vevent in vevents:
|
|
vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
|
|
if vevent.mode_remark:
|
|
vevent.SUMMARY += vevent.mode_remark
|
|
vevent.save()
|
|
|
|
ds = False
|
|
dc = False
|
|
|
|
for lesion in lesions:
|
|
if lesion.start_date != None:
|
|
if not ds or lesion.start_date < ds:
|
|
ds = lesion.start_date
|
|
if lesion.end_date != None:
|
|
if not dc or lesion.end_date > dc:
|
|
dc = lesion.end_date
|
|
|
|
if not ds:
|
|
for vevent in vevents:
|
|
if vevent.mode != 310:
|
|
continue
|
|
if not ds or vevent.DTSTART.date() < ds:
|
|
ds = vevent.DTSTART.date()
|
|
if not dc or vevent.DTSTART.date() > dc:
|
|
dc = vevent.DTSTART.date()
|
|
|
|
if not ds:
|
|
for vevent in vevents:
|
|
if not ds or vevent.DTSTART.date() < ds:
|
|
ds = vevent.DTSTART.date()
|
|
if not dc or vevent.DTSTART.date() > dc:
|
|
dc = vevent.DTSTART.date()
|
|
|
|
if ds and treatment.date_started != ds:
|
|
treatment.date_started = ds
|
|
treatment.save()
|
|
if dc and treatment.date_completed != dc:
|
|
treatment.date_completed = dc
|
|
treatment.save()
|
|
|
|
nhiorders = NHIOrder.objects.filter(ChartNo=patient.medical_records)
|
|
|
|
# response = render_to_response("ck/treatment_detail.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatment": treatment,
|
|
# "vevents": vevents,
|
|
# "lesions": lesions,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, 'ck/treatment_detail.html',
|
|
{
|
|
"patient": patient,
|
|
"treatment": treatment,
|
|
"vevents": vevents,
|
|
"lesions": lesions,
|
|
"nhiorders": nhiorders,
|
|
}
|
|
)
|
|
response.set_cookie('patient', patient.id)
|
|
request.session['patient'] = patient.id
|
|
response.set_cookie('treatment', object_id)
|
|
request.session['treatment'] = object_id
|
|
return response
|
|
|
|
|
|
|
|
@login_required
|
|
def treatment_print(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('treatment')
|
|
treatment = Treatment.objects.get(id=object_id)
|
|
patient = Patient.objects.get(id=treatment.patient_id)
|
|
if object_id:
|
|
qset = (
|
|
Q(treatment=object_id)
|
|
)
|
|
vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
|
|
lesions = Lesion.objects.filter(qset).distinct()
|
|
else:
|
|
vevents = []
|
|
lesions = []
|
|
|
|
# update treatment date_completed
|
|
|
|
dc = treatment.date_completed
|
|
|
|
for vevent in vevents:
|
|
vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
|
|
if vevent.mode_remark:
|
|
vevent.SUMMARY += vevent.mode_remark
|
|
vevent.save()
|
|
if vevent.DTSTART.date() > dc:
|
|
dc = vevent.DTSTART.date()
|
|
|
|
if treatment.date_completed != dc:
|
|
treatment.date_completed = dc
|
|
treatment.save()
|
|
|
|
paginator = Paginator(lesions, 3) # Show 3 lesions per page
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
try:
|
|
page = int(request.GET.get('page', '1'))
|
|
except ValueError:
|
|
page = 1
|
|
|
|
# If page request (9999) is out of range, deliver last page of results.
|
|
try:
|
|
contacts = paginator.page(page)
|
|
except (EmptyPage, InvalidPage):
|
|
contacts = paginator.page(paginator.num_pages)
|
|
|
|
# response = render_to_response("ck/treatment_print.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatment": treatment,
|
|
# "vevents": vevents,
|
|
# "contacts": contacts,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, 'ck/treatment_print.html',
|
|
{
|
|
"patient": patient,
|
|
"treatment": treatment,
|
|
"vevents": vevents,
|
|
"contacts": contacts,
|
|
}
|
|
)
|
|
response.set_cookie('patient', object_id)
|
|
request.session['patient'] = object_id
|
|
response.set_cookie('treatment', object_id)
|
|
request.session['treatment'] = object_id
|
|
return response
|
|
|
|
|
|
@login_required
|
|
def treatment_record(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('treatment')
|
|
treatment = Treatment.objects.get(id=object_id)
|
|
patient = Patient.objects.get(id=treatment.patient_id)
|
|
if object_id:
|
|
qset = (
|
|
Q(treatment=object_id)
|
|
)
|
|
vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
|
|
lesions = Lesion.objects.filter(qset).distinct()
|
|
else:
|
|
vevents = []
|
|
lesions = []
|
|
|
|
# update treatment date_completed
|
|
|
|
dc = treatment.date_completed
|
|
|
|
for vevent in vevents:
|
|
vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
|
|
if vevent.mode_remark:
|
|
vevent.SUMMARY += vevent.mode_remark
|
|
vevent.save()
|
|
if vevent.DTSTART.date() > dc:
|
|
dc = vevent.DTSTART.date()
|
|
|
|
if treatment.date_completed != dc:
|
|
treatment.date_completed = dc
|
|
treatment.save()
|
|
|
|
# response = render_to_response("ck/treatment_record.html",
|
|
# response = render_to_response("ck/brief_history.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatment": treatment,
|
|
# "vevents": vevents,
|
|
# "lesions": lesions,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, 'ck/brief_history.html',
|
|
{
|
|
"patient": patient,
|
|
"treatment": treatment,
|
|
"vevents": vevents,
|
|
"lesions": lesions,
|
|
}
|
|
)
|
|
response.set_cookie('patient', object_id)
|
|
request.session['patient'] = object_id
|
|
response.set_cookie('treatment', object_id)
|
|
request.session['treatment'] = object_id
|
|
return response
|
|
|
|
|
|
@login_required
|
|
def treatment_report(request, object_id):
|
|
if object_id=='':
|
|
object_id = request.session.get('treatment')
|
|
treatment = Treatment.objects.get(id=object_id)
|
|
patient = Patient.objects.get(id=treatment.patient_id)
|
|
if object_id:
|
|
qset = (
|
|
Q(treatment=object_id)
|
|
)
|
|
vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
|
|
lesions = Lesion.objects.filter(qset).distinct()
|
|
else:
|
|
vevents = []
|
|
lesions = []
|
|
|
|
# update treatment date_completed
|
|
|
|
dc = treatment.date_completed
|
|
|
|
for vevent in vevents:
|
|
vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
|
|
if vevent.mode_remark:
|
|
vevent.SUMMARY += vevent.mode_remark
|
|
vevent.save()
|
|
if vevent.DTSTART.date() > dc:
|
|
dc = vevent.DTSTART.date()
|
|
|
|
if treatment.date_completed != dc:
|
|
treatment.date_completed = dc
|
|
treatment.save()
|
|
|
|
paginator = Paginator(lesions, 5) # Show 25 contacts per page
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
try:
|
|
page = int(request.GET.get('page', '1'))
|
|
except ValueError:
|
|
page = 1
|
|
|
|
# If page request (9999) is out of range, deliver last page of results.
|
|
try:
|
|
contacts = paginator.page(page)
|
|
except (EmptyPage, InvalidPage):
|
|
contacts = paginator.page(paginator.num_pages)
|
|
|
|
# response = render_to_response("ck/treatment_report.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "treatment": treatment,
|
|
# "vevents": vevents,
|
|
# "contacts": contacts,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, 'ck/treatment_report.html',
|
|
{
|
|
"patient": patient,
|
|
"treatment": treatment,
|
|
"vevents": vevents,
|
|
"contacts": contacts,
|
|
}
|
|
)
|
|
response.set_cookie('patient', object_id)
|
|
request.session['patient'] = object_id
|
|
response.set_cookie('treatment', object_id)
|
|
request.session['treatment'] = object_id
|
|
return response
|
|
|
|
|
|
class TreatmentUpdate(UpdateView):
|
|
model = Treatment
|
|
form_class = TreatmentForm
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
print(context)
|
|
context["topicd10"] = top_icd10
|
|
context['nhiorders'] = NHIOrder.objects.filter(ChartNo=self.object.patient.medical_records)
|
|
return context
|
|
|
|
|
|
@login_required
|
|
def treatment_update(request, object_id):
|
|
if request.method == 'POST':
|
|
# TreatmentForm = form_for_model(Treatment)
|
|
form = TreatmentForm(request.POST)
|
|
# print dir(form)
|
|
logging.info(dir(form))
|
|
form.save()
|
|
return HttpResponseRedirect('/treatment/list/')
|
|
|
|
treatment = Treatment.objects.get(id=object_id)
|
|
patient = Patient.objects.get(id=treatment.patient.id)
|
|
# TreatmentForm = form_for_instance(treatment)
|
|
form = TreatmentForm(instance=treatment)
|
|
# response = render_to_response("ck/treatment_form2.html",
|
|
# response = render_to_response("ck/treatment_form.html",
|
|
# {
|
|
# "form": form,
|
|
# "patient": patient,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, "ck/treatment_form.html",
|
|
{
|
|
"form": form,
|
|
"patient": patient,
|
|
}
|
|
)
|
|
response.set_cookie('treatment', object_id)
|
|
request.session['treatment'] = object_id
|
|
return response
|
|
|
|
|
|
class TreatmentDatatableView(XEditableDatatableView):
|
|
model = Treatment
|
|
|
|
def setup(self, request, *args, **kwargs):
|
|
super().setup(request, *args, **kwargs)
|
|
if request.GET.get('download') is not None:
|
|
QueryMS()
|
|
|
|
class datatable_class(Datatable):
|
|
|
|
|
|
patient_name = columns.TextColumn ('Name', sources=['patient__name'])
|
|
medical_records = columns.TextColumn ('MRN', sources=['patient__medical_records'])
|
|
date = columns.CompoundColumn('Date', sources=['date_started', 'date_completed'])
|
|
get_accounting_display = columns.TextColumn ('記帳', sources=['get_accounting_display'])
|
|
|
|
# django.core.exceptions.FieldError: Related Field got invalid lookup: icontains
|
|
icd10 = columns.TextColumn ('ICD10', processor='ProcessICD10', sources=['icd10cm__ICD10CM'])
|
|
icd9 = columns.TextColumn ('ICD9', processor='ProcessICD9', sources=['icd9__code'])
|
|
|
|
detail = columns.DisplayColumn('Detail' , processor='ProcessDetail')
|
|
operations = columns.DisplayColumn('Operations', processor='ProcessOperations')
|
|
|
|
def ProcessICD10(self, *args, **kwargs):
|
|
data = args[0]
|
|
|
|
if data.icd10cm is None:
|
|
return f'<div class="bg-danger text-white">None</div>'
|
|
if data.icd10cm.ICD10CM not in top_icd10_list(10):
|
|
return f'<div class="bg-danger text-white" title="{data.icd10cm.ICD10CM_English}">{data.icd10cm.ICD10CM}</div>'
|
|
if data.icd10cm.ICD10CM not in top_icd10_list(5):
|
|
return f'<div class="bg-warning text-dark" title="{data.icd10cm.ICD10CM_English}">{data.icd10cm.ICD10CM}</div>'
|
|
|
|
return f'<div class="bg-success text-white" title="{data.icd10cm.ICD10CM_English}">{data.icd10cm.ICD10CM}</div>'
|
|
return str(data.icd10cm)
|
|
if data.icd10cm is None:
|
|
return None
|
|
return f'<span title="{data.icd10cm.ICD10CM_English}">{data.icd10cm.ICD10CM}</span>'
|
|
|
|
def ProcessICD9(self, *args, **kwargs):
|
|
data = args[0]
|
|
if data.icd9 is None:
|
|
return '<div class="bg-danger text-white">None</div>'
|
|
return f'<div class="bg-success text-white" title="{data.icd9.desc}">{data.icd9.code}</div>'
|
|
return str(data.icd9)
|
|
|
|
def ProcessDetail(self, *args, **kwargs):
|
|
data = args[0]
|
|
return f'''
|
|
<a href="{reverse('treatment-detail', kwargs={'object_id': data.id})}"><span class="material-icons-outlined">launch</span></a>
|
|
'''
|
|
|
|
def ProcessOperations(self, *args, **kwargs):
|
|
data = args[0]
|
|
# print(data)
|
|
# default_value = kwargs['default_value']
|
|
return f'''
|
|
<a href="{reverse('treatment-update', kwargs={'pk': data.id})}"><span class="material-icons-outlined">edit</span></a>
|
|
<a href="{reverse('treatment-delete', kwargs={'pk': data.id})}"><span class="material-icons-outlined">delete</span></a>
|
|
'''
|
|
|
|
class Meta:
|
|
ordering = ['-id']
|
|
|
|
columns = [
|
|
'detail',
|
|
|
|
'id',
|
|
'patient_name',
|
|
'medical_records',
|
|
# 'date_started',
|
|
# 'date_completed',
|
|
'date',
|
|
'oncologist',
|
|
'surgeon',
|
|
'get_accounting_display',
|
|
'disease_stage',
|
|
'primary_tumor_site',
|
|
# 'icd10cm',
|
|
'icd10',
|
|
'icd9',
|
|
'other_diagnosis',
|
|
'input',
|
|
'output',
|
|
'bed',
|
|
'memo',
|
|
|
|
'operations',
|
|
]
|
|
|
|
processors = {
|
|
'memo': helpers.make_xeditable(),
|
|
}
|
|
|
|
# request_method = 'POST' # make_xeditable will not work with post??
|
|
|
|
# search_fields = [
|
|
# # 'patient__medical_records'
|
|
# 'memo',
|
|
# ]
|
|
|
|
|
|
class FinishedTreatmentDatatableView(TreatmentDatatableView):
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
return queryset.filter(**self.request.GET.dict())
|
|
|
|
@login_required
|
|
def followup_newimages(request):
|
|
|
|
renew = request.REQUEST.get('renew', False)
|
|
|
|
if renew:
|
|
kd22.renew(PACSImage)
|
|
|
|
date_query = Treatment.objects.values('patient_id').annotate(started=Min('date_started'),completed=Max('date_completed'))
|
|
images = PACSImage.objects.filter(Q(Saved = 0),Q(Modality__startswith='CT')|Q(Modality__startswith='MR')).order_by('-ExamDate')[:100]
|
|
results = []
|
|
|
|
|
|
|
|
blank = 0
|
|
|
|
for image in images:
|
|
if blank > 50:
|
|
break
|
|
try:
|
|
treat_date = date_query.get(patient=image.patient)
|
|
except:
|
|
continue
|
|
if image.ExamDate > treat_date['completed']:
|
|
try:
|
|
LF = LesionFollow.objects.get(Q(Lesion__treatment__patient = image.patient),Q(Date = image.ExamDate))
|
|
image.Saved = 10 #有輸入
|
|
except:
|
|
pass
|
|
results.append(image)
|
|
if image.Saved == 0:
|
|
blank += 1
|
|
|
|
return render(request, "ck/followup_newimages.html",
|
|
{
|
|
"images": results,
|
|
}
|
|
)
|
|
return render_to_response("ck/followup_newimages.html",
|
|
{
|
|
"images": results,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
@login_required
|
|
def followup_markimages(request, RequestSheetNo, Saved):
|
|
image = PACSImage.objects.get(Q(RequestSheetNo = RequestSheetNo))
|
|
image.Saved = Saved
|
|
image.save()
|
|
return HttpResponseRedirect('/followup/newimages/')
|
|
|
|
@login_required
|
|
def followup_nosee1(request):
|
|
treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
|
|
followup_date = Followup.objects.values('patient_id').annotate(first=Min('date'),last=Max('date'))
|
|
record_date = MedicalRecord.objects.values('patient_id').annotate(first=Min('InDate'),last=Max('InDate'))
|
|
image_date = PACSImage.objects.values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
|
|
|
|
patients = Patient.objects.all()
|
|
results = []
|
|
# n = datetime.datetime.now()
|
|
for patient in patients:
|
|
if patient.dead:
|
|
continue
|
|
|
|
try:
|
|
d = treatment_date.get(patient=patient)
|
|
date = d['last']
|
|
except:
|
|
# print "%s no treatment" % patient.id
|
|
continue
|
|
|
|
try:
|
|
d = followup_date.get(patient=patient)
|
|
if d['last'] > date:
|
|
date = d['last']
|
|
except:
|
|
# print "%s no follow" % patient.id
|
|
pass
|
|
|
|
try:
|
|
d = record_date.get(patient=patient)
|
|
if d['last'] > date:
|
|
date = d['last']
|
|
except:
|
|
# print "%s no record" % patient.id
|
|
pass
|
|
|
|
try:
|
|
d = image_date.get(patient=patient)
|
|
if d['last'] > date:
|
|
date = d['last']
|
|
except:
|
|
# print "%s no image" % patient.id
|
|
pass
|
|
|
|
# results['patient.id']=date
|
|
results.append((patient, date))
|
|
|
|
# print results
|
|
results = sorted(results, key=lambda last: last[1])[:25]
|
|
# print datetime.datetime.now() - n
|
|
# print results
|
|
|
|
return render(request, "ck/followup_nosee.html",
|
|
{
|
|
"results": results,
|
|
}
|
|
)
|
|
return render_to_response("ck/followup_nosee.html",
|
|
{
|
|
"results": results,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
@login_required
|
|
def followup_nosee(request):
|
|
###Load all dates into hash first
|
|
treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
|
|
t = {}
|
|
for item in treatment_date:
|
|
t[item['patient_id']] = item['last']
|
|
|
|
followup_date = Followup.objects.values('patient_id').annotate(first=Min('date'),last=Max('date'))
|
|
f = {}
|
|
for item in followup_date:
|
|
f[item['patient_id']] = item['last']
|
|
|
|
record_date = MedicalRecord.objects.values('patient_id').annotate(first=Min('InDate'),last=Max('InDate'))
|
|
r = {}
|
|
for item in record_date:
|
|
r[item['patient_id']] = item['last']
|
|
|
|
image_date = PACSImage.objects.values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
|
|
i = {}
|
|
for item in image_date:
|
|
i[item['patient_id']] = item['last']
|
|
|
|
patients = Patient.objects.all()
|
|
results = []
|
|
# n = datetime.datetime.now()
|
|
for patient in patients:
|
|
if patient.dead:
|
|
continue
|
|
|
|
try:
|
|
d = t[patient.id]
|
|
date = d
|
|
except:
|
|
# print "%s no treatment" % patient.id
|
|
continue
|
|
|
|
try:
|
|
d = f[patient.id]
|
|
if d > date:
|
|
date = d
|
|
except:
|
|
# print "%s no follow" % patient.id
|
|
pass
|
|
|
|
try:
|
|
d = r[patient.id]
|
|
if d > date:
|
|
date = d
|
|
except:
|
|
# print "%s no record" % patient.id
|
|
pass
|
|
|
|
try:
|
|
d = i[patient.id]
|
|
if d > date:
|
|
date = d
|
|
except:
|
|
# print "%s no image" % patient.id
|
|
pass
|
|
|
|
# results['patient.id']=date
|
|
results.append((patient, date))
|
|
|
|
# print results
|
|
results = sorted(results, key=lambda last: last[1])[:25]
|
|
# print datetime.datetime.now() - n
|
|
# print results
|
|
|
|
model = Patient
|
|
form_class = None
|
|
model, form_class = create_update.get_model_and_form_class(model, form_class)
|
|
form = form_class()
|
|
|
|
return render(request, "ck/followup_nosee.html",
|
|
{
|
|
"results": results,
|
|
"form": form,
|
|
}
|
|
)
|
|
return render_to_response("ck/followup_nosee.html",
|
|
{
|
|
"results": results,
|
|
"form": form,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
@login_required
|
|
def followup_image_long(request):
|
|
###Load all dates into hash first
|
|
treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
|
|
t = {}
|
|
for item in treatment_date:
|
|
t[item['patient_id']] = item['first']
|
|
|
|
image_date = PACSImage.objects.filter(Saved__in=[0,10]).values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
|
|
i = {}
|
|
for item in image_date:
|
|
i[item['patient_id']] = item['last']
|
|
|
|
v = {}
|
|
follows = LesionFollow.objects.select_related().all()
|
|
# print follows
|
|
for follow in follows:
|
|
if not v.has_key(follow.Lesion.treatment.patient.id):
|
|
v[follow.Lesion.treatment.patient.id] = follow.Date
|
|
else:
|
|
v[follow.Lesion.treatment.patient.id] = max(follow.Date, v[follow.Lesion.treatment.patient.id])
|
|
|
|
# print v
|
|
|
|
|
|
|
|
# patients = Patient.objects.select_related().all()
|
|
patients = Patient.objects.all()
|
|
|
|
results = []
|
|
# n = datetime.datetime.now()
|
|
# print t
|
|
# print i
|
|
for patient in patients:
|
|
if patient.dead:
|
|
continue
|
|
|
|
try:
|
|
d = t[patient.id]
|
|
tdate = d
|
|
except:
|
|
# print "%s no treatment" % patient.id
|
|
continue
|
|
|
|
try:
|
|
d = i[patient.id]
|
|
idate = d
|
|
except:
|
|
# print "%s no image" % patient.id
|
|
continue
|
|
|
|
daydiff = (idate-tdate).days
|
|
if daydiff < 365:
|
|
continue
|
|
|
|
try:
|
|
d = v[patient.id]
|
|
vdate = d
|
|
except:
|
|
# print "%s no image" % patient.id
|
|
vdate = ''
|
|
|
|
|
|
|
|
# results['patient.id']=date
|
|
results.append((patient, daydiff, tdate, idate, vdate))
|
|
|
|
# print type(idate-tdate)
|
|
# print results
|
|
results = sorted(results, key=lambda last: -last[1])
|
|
# print datetime.datetime.now() - n
|
|
# print results
|
|
|
|
# model = Patient
|
|
# form_class = None
|
|
# model, form_class = create_update.get_model_and_form_class(model, form_class)
|
|
# form = form_class()
|
|
|
|
return render(request, "ck/followup_image_long.html",
|
|
{
|
|
"results": results,
|
|
}
|
|
)
|
|
return render_to_response("ck/followup_image_long.html",
|
|
{
|
|
"results": results,
|
|
# "form": form,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
@login_required
|
|
def followup_new_volume(request,object_id):
|
|
# print request
|
|
# print 'object_id=', object_id
|
|
|
|
idate = ''
|
|
|
|
p = request.POST
|
|
# print p
|
|
if p.has_key('Lesion'):
|
|
lesion = Lesion.objects.get(id=p['Lesion'])
|
|
|
|
f = lambda x:None if x == '' else x
|
|
|
|
l = LesionFollow(
|
|
Lesion = lesion,
|
|
Date = p['Date'],
|
|
Volume = f(p['Volume']),
|
|
A = f(p['A']),
|
|
B = f(p['B']),
|
|
C = f(p['C']),
|
|
Memo = p['Memo'],
|
|
)
|
|
l.save()
|
|
idate = p['Date']
|
|
|
|
try:
|
|
idate = request.GET['idate']
|
|
except:
|
|
idate = request.COOKIES['date']
|
|
|
|
try:
|
|
patient = Patient.objects.get(id=object_id)
|
|
except:
|
|
patient = Patient.objects.get(id=request.COOKIES['patient'])
|
|
|
|
model = LesionFollow
|
|
form_class = None
|
|
model, form_class = create_update.get_model_and_form_class(model, form_class)
|
|
form = form_class()
|
|
|
|
# response = render_to_response("ck/followup_new_volume.html",
|
|
# {
|
|
# "patient": patient,
|
|
# "idate": idate,
|
|
# "form": form,
|
|
# }, context_instance=RequestContext(request))
|
|
response = render(request, "ck/followup_new_volume.html",
|
|
{
|
|
"patient": patient,
|
|
"idate": idate,
|
|
"form": form,
|
|
}
|
|
)
|
|
response.set_cookie('patient', patient.id)
|
|
response.set_cookie('date', idate)
|
|
return response
|
|
|
|
|
|
########## AJAX
|
|
|
|
@login_required
|
|
def below(request):
|
|
return render(reuqest, 'ck/below.html')
|
|
return render_to_response('ck/below.html')
|
|
|
|
@login_required
|
|
def get_target_location(request):
|
|
# return HttpResponse(django.core.serializers.serialize("xml", TargetLocation.objects.all()))
|
|
return HttpResponse(django.core.serializers.serialize("json", TargetLocation.objects.all()))
|
|
|
|
@login_required
|
|
def get_sublocation(request):
|
|
i = request.GET.get('id', None)
|
|
if i:
|
|
return HttpResponse(django.core.serializers.serialize("json", SubLocation.objects.filter(id=i)))
|
|
target = request.GET.get('target', None)
|
|
return HttpResponse(django.core.serializers.serialize("json", SubLocation.objects.filter(target_location=target)))
|
|
|
|
@login_required
|
|
def get_pathology(request):
|
|
sl = request.GET.get('sublocation', '')
|
|
return HttpResponse(django.core.serializers.serialize("json", Pathology.objects.filter(sublocation=sl)))
|
|
|
|
def get_icd9cm(request):
|
|
id = request.GET.get('id', False)
|
|
name = request.GET.get('q', '')
|
|
limit = request.GET.get('s', 99)
|
|
|
|
if (name.count('.')):
|
|
name = name.replace('.', '')[0:5].rstrip()
|
|
if id:
|
|
codes = ICD9Diag.objects.filter(code=id)
|
|
elif len(name):
|
|
qset = (
|
|
Q(code__istartswith=name) |
|
|
# Q(code__istartswith='0'+name) |
|
|
# Q(code__istartswith='00'+name) |
|
|
Q(desc__icontains=name)
|
|
)
|
|
codes = ICD9Diag.objects.filter(qset)[:100]
|
|
else:
|
|
codes =ICD9Diag.objects.all()[:100]
|
|
|
|
ret = """
|
|
[
|
|
"""
|
|
|
|
# ret = '{"results":['
|
|
|
|
for code in codes:
|
|
# ret += '["%s","%s"],' % (code.code, code)
|
|
ret += '["%s","%s"],' % (code, code.code)
|
|
# ret += '\n{"id":"%s","name":"%s"},' % (code.code, code)
|
|
|
|
|
|
ret = ret[:-1]+"""
|
|
]
|
|
"""
|
|
|
|
|
|
return HttpResponse(ret)
|
|
|
|
|
|
def get_icd9cm_old(request):
|
|
id = request.GET.get('id', False)
|
|
name = request.GET.get('name', '')[:-1]
|
|
if (name.count('.')):
|
|
name = name.replace('.', '')[0:5].rstrip()
|
|
if id:
|
|
codes = ICD9Diag.objects.filter(code=id)
|
|
elif len(name):
|
|
qset = (
|
|
Q(code__istartswith=name) |
|
|
# Q(code__istartswith='0'+name) |
|
|
# Q(code__istartswith='00'+name) |
|
|
Q(desc__icontains=name)
|
|
)
|
|
codes = ICD9Diag.objects.filter(qset)[:100]
|
|
else:
|
|
codes =ICD9Diag.objects.all()[:100]
|
|
|
|
ret = """
|
|
{ 'identifier': 'code',
|
|
'label': 'name',
|
|
'items': [
|
|
"""
|
|
|
|
# ret = '{"results":['
|
|
|
|
for code in codes:
|
|
ret += '\n{"code":"%s","name":"%s"},' % (code.code, code)
|
|
# ret += '\n{"id":"%s","name":"%s"},' % (code.code, code)
|
|
|
|
|
|
ret = ret[:-1]+"]}"
|
|
|
|
|
|
return HttpResponse(ret)
|
|
|
|
|
|
def get_followup(request):
|
|
date = request.GET.get('date', '')
|
|
if date:
|
|
d = mx.DateTime.DateTimeFrom(date)
|
|
fr = d + mx.DateTime.RelativeDateTime(weeks=-6)
|
|
to = d + mx.DateTime.RelativeDateTime(weeks=+6)
|
|
events = Patient.objects.filter(next_followup__range=(fr, to))
|
|
else:
|
|
events = Patient.objects.all()
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", events, ensure_ascii=False))
|
|
|
|
|
|
def get_vevent_old(request):
|
|
date = request.GET.get('date', '')
|
|
if date:
|
|
d = mx.DateTime.DateTimeFrom(date)
|
|
fr = d + mx.DateTime.RelativeDateTime(weeks=-6)
|
|
to = d + mx.DateTime.RelativeDateTime(weeks=+6)
|
|
events = VEVENT.objects.filter(DTSTART__range=(fr, to))
|
|
else:
|
|
events = VEVENT.objects.all()
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", events, ensure_ascii=False))
|
|
|
|
# '''
|
|
# DataDumper
|
|
# '''
|
|
#
|
|
# import types
|
|
# from django.db import models
|
|
# import pyxslt.serialize
|
|
# from django.utils import simplejson as json
|
|
# from django.core.serializers.json import DateTimeAwareJSONEncoder
|
|
# from decimal import *
|
|
#
|
|
# class DataDumper:
|
|
# fields = {}
|
|
# def selectObjectFields(self,objectType,fields = []):
|
|
# self.fields[objectType] = fields
|
|
#
|
|
# def dump(self,data,format='xml'):
|
|
# """
|
|
# The main issues with django's default json serializer is that properties that
|
|
# had been added to a object dynamically are being ignored (and it also has
|
|
# problems with some models).
|
|
# """
|
|
#
|
|
# def _any(data):
|
|
# ret = None
|
|
# if type(data) is types.ListType:
|
|
# ret = _list(data)
|
|
# elif type(data) is types.DictType:
|
|
# ret = _dict(data)
|
|
# elif isinstance(data, Decimal):
|
|
# # json.dumps() cant handle Decimal
|
|
# ret = str(data)
|
|
# elif isinstance(data, models.query.QuerySet):
|
|
# # Actually its the same as a list ...
|
|
# ret = _list(data)
|
|
# elif isinstance(data, models.Model):
|
|
# ret = _model(data)
|
|
# else:
|
|
# ret = data
|
|
# return ret
|
|
#
|
|
# def _model(data):
|
|
# ret = {}
|
|
# # If we only have a model, we only want to encode the fields.
|
|
# objType = data.__class__.__name__
|
|
# for f in data._meta.fields:
|
|
# if (self.fields[objType]) and (f.attname in self.fields[objType]):
|
|
# ret[f.attname] = _any(getattr(data, f.attname))
|
|
# # And additionally encode arbitrary properties that had been added.
|
|
# fields = dir(data.__class__) + ret.keys()
|
|
# add_ons = [k for k in dir(data) if k not in fields]
|
|
# for k in add_ons:
|
|
# if (self.fields[objType]) and (k in self.fields[objType]):
|
|
# ret[k] = _any(getattr(data, k))
|
|
# return ret
|
|
# def _list(data):
|
|
# ret = []
|
|
# for v in data:
|
|
# ret.append(_any(v))
|
|
# return ret
|
|
#
|
|
# def _dict(data):
|
|
# ret = {}
|
|
# for k,v in data.items():
|
|
# ret[k] = _any(v)
|
|
# return ret
|
|
#
|
|
# ret = _any(data)
|
|
# if(format == 'xml'):
|
|
# return pyxslt.serialize.toString(prettyPrintXml=False,data=ret,)
|
|
# else:
|
|
# return json.dumps(ret, cls=DateTimeAwareJSONEncoder)
|
|
#
|
|
# '''
|
|
# DataDumper
|
|
# '''
|
|
|
|
@login_required
|
|
def get_vevent(request):
|
|
events = VEVENT.objects.extra(select={
|
|
'title' : "SUMMARY",
|
|
'allDay': "false",
|
|
# 'start' : "UNIX_TIMESTAMP(DATE_SUB(DTSTART, INTERVAL 8 HOUR))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DATE_SUB(DTSTART, INTERVAL 8 HOUR),DURATION))",
|
|
'start' : "UNIX_TIMESTAMP(DTSTART)",
|
|
'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,MAX(DURATION,'00:30:00')))",
|
|
'url' : "CONCAT('/event/update/',id,'/')",
|
|
})
|
|
|
|
start = request.GET.get('start', '')
|
|
end = request.GET.get('end' , '')
|
|
|
|
if start:
|
|
# fr = datetime.datetime.fromtimestamp(float(start))
|
|
# to = datetime.datetime.fromtimestamp(float(end))
|
|
fr = start
|
|
to = end
|
|
events = events.filter(DTSTART__range=(fr, to))
|
|
|
|
# dumper = DataDumper()
|
|
# dumper.selectObjectFields('VEVENT', ['id', 'title', 'allDay', 'start', 'end', 'url'])
|
|
# dumper.dump(events,'json')
|
|
|
|
# return HttpResponse(dumper.dump(events,'json'))
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", events))
|
|
|
|
# return HttpResponse(django.core.serializers.serialize("json", events, ensure_ascii=False))
|
|
|
|
# entries = []
|
|
# for event in events:
|
|
# starttime = mx.DateTime.DateTimeFrom(event.DTSTART.isoformat())
|
|
# duration = mx.DateTime.DateTimeDeltaFrom(hours=event.DURATION.hour, minutes=event.DURATION.minute)
|
|
# endtime = starttime + duration
|
|
# entry = {
|
|
# 'id': event.id,
|
|
# 'starttime': starttime.strftime('%Y-%m-%dT%H:%M:%S'),
|
|
# 'endtime': starttime.strftime('%Y-%m-%dT%H:%M:%S'),
|
|
# 'allday': False,
|
|
# 'repeated': False,
|
|
# 'title': event.treatment.patient.name + event.get_mode_display(),
|
|
# 'url': "/treatment/detail/%i/" % event.treatment.id,
|
|
# 'body': event.SUMMARY,
|
|
# 'attributes': {
|
|
# 'Oncologist': event.treatment.oncologist.name,
|
|
# 'Surgeon': event.treatment.surgeon.name,
|
|
# },
|
|
# 'type': [event.get_mode_display(), event.get_mode_display()]
|
|
# }
|
|
# entries.append(entry)
|
|
# return HttpResponse(django.core.serializers.serialize("xml", entries, ensure_ascii=False))
|
|
|
|
@login_required
|
|
def event_drop(request):
|
|
|
|
id = request.GET.get('id' , '')
|
|
dayDelta = int(request.GET.get('dayDelta' , ''))
|
|
minuteDelta = int(request.GET.get('minuteDelta', ''))
|
|
|
|
vevent = VEVENT.objects.get(id=id)
|
|
t = vevent.DTSTART
|
|
start = mx.DateTime.DateTime(t.year,t.month,t.day,t.hour,t.minute,t.second+1e-6*t.microsecond)
|
|
start = start + mx.DateTime.RelativeDateTime(days=dayDelta) + mx.DateTime.RelativeDateTime(minutes=minuteDelta)
|
|
vevent.DTSTART = datetime.datetime.fromtimestamp(start)
|
|
vevent.save()
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))
|
|
|
|
@login_required
|
|
def event_resize(request):
|
|
|
|
id = request.GET.get('id' , '')
|
|
dayDelta = int(request.GET.get('dayDelta' , ''))
|
|
minuteDelta = int(request.GET.get('minuteDelta', ''))
|
|
|
|
vevent = VEVENT.objects.get(id=id)
|
|
t = vevent.DURATION
|
|
d = datetime.timedelta(days=dayDelta,minutes=minuteDelta)
|
|
dt = datetime.datetime.combine(datetime.date.today(), t) + d
|
|
vevent.DURATION = dt.time()
|
|
vevent.save()
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))
|
|
|
|
@login_required
|
|
def update_vevent(request):
|
|
|
|
# id = request.GET.get('id', '')
|
|
# starttime = request.GET.get('starttime', '')
|
|
# endtime = request.GET.get('endtime', '')
|
|
|
|
id = request.POST.get('id', '')
|
|
starttime = mx.DateTime.DateTimeFrom(request.POST.get('starttime', '')[:-6])
|
|
endtime = mx.DateTime.DateTimeFrom(request.POST.get('endtime', '')[:-6])
|
|
duration = mx.DateTime.Age(endtime, starttime)
|
|
duration = str(duration.hours)+':'+str(duration.minutes)
|
|
|
|
logging.info(id, starttime, endtime, duration)
|
|
|
|
vevent = VEVENT.objects.get(id=id)
|
|
vevent.DTSTART = starttime
|
|
# vevent.DURATION = duration
|
|
vevent.save()
|
|
|
|
return HttpResponse(django.core.serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))
|
|
# return HttpResponse("")
|
|
|
|
|
|
def listCalendarByRange(sd, ed, cnt):
|
|
# print ret
|
|
# $title = array('team meeting', 'remote meeting', 'project plan review', 'annual report', 'go to dinner');
|
|
# $location = array('Lodan', 'Newswer', 'Belion', 'Moore', 'Bytelin');
|
|
|
|
|
|
events = VEVENT.objects.extra(select={
|
|
'title' : "SUMMARY",
|
|
'allDay': "false",
|
|
# 'start' : "UNIX_TIMESTAMP(DATE_SUB(DTSTART, INTERVAL 8 HOUR))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DATE_SUB(DTSTART, INTERVAL 8 HOUR),DURATION))",
|
|
'start' : "UNIX_TIMESTAMP(DTSTART)",
|
|
'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
|
|
# 'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,MAX(DURATION,'00:30:00')))",
|
|
'url' : "CONCAT('/event/update/',id,'/')",
|
|
})
|
|
|
|
events = events.filter(DTSTART__range=(sd, ed))
|
|
# print events
|
|
|
|
revents = []
|
|
|
|
for event in events:
|
|
d = event.DURATION
|
|
revent = (event.id,
|
|
event.title,
|
|
event.DTSTART.isoformat(),
|
|
(event.DTSTART+datetime.timedelta(minutes=d.minute, hours=d.hour)).isoformat(),
|
|
0, #IsAllDayEvent
|
|
0, #more than one day event
|
|
0, #Recurring event
|
|
event.id % 14, #Color
|
|
1, #editable
|
|
dict(event.MODE_CHOICES).get(event.mode,''), #Location
|
|
'', #attends
|
|
)
|
|
logging.info(revent)
|
|
revents.append(revent)
|
|
|
|
ret = {}
|
|
ret['events'] = revents
|
|
ret["issort"] = True
|
|
ret["start"] = sd.isoformat()
|
|
ret["end"] = ed.isoformat()
|
|
ret['error'] = None
|
|
|
|
return ret
|
|
|
|
|
|
def listCalendar(day, type):
|
|
date = datetime.datetime.strptime(day, '%m/%d/%Y')
|
|
logging.info(date)
|
|
if type == 'month':
|
|
st = date - datetime.timedelta(31)
|
|
et = date + datetime.timedelta(31)
|
|
cnt = 50
|
|
elif type == 'week':
|
|
st = date - datetime.timedelta(7)
|
|
et = date + datetime.timedelta(7)
|
|
cnt = 20
|
|
elif type == 'day':
|
|
st = date - datetime.timedelta(1)
|
|
et = date + datetime.timedelta(1)
|
|
cnt = 5
|
|
|
|
return listCalendarByRange(st, et, cnt)
|
|
|
|
#@login_required
|
|
def datafeed(request):
|
|
|
|
try:
|
|
|
|
# print request
|
|
method = request.GET['method']
|
|
# print method
|
|
|
|
if method == 'add':
|
|
pass
|
|
elif method == 'list':
|
|
ret = listCalendar(request.POST['showdate'], request.POST['viewtype'])
|
|
elif method == 'update':
|
|
pass
|
|
elif method == 'remove':
|
|
pass
|
|
elif method == 'adddetails':
|
|
pass
|
|
|
|
except:
|
|
ret = listCalendar('8/3/2011', 'month')
|
|
|
|
dumper = DataDumper()
|
|
return HttpResponse(dumper.dump(ret,'json'))
|
|
|
|
# class VEVENT_ViewSet(viewsets.ModelViewSet):
|
|
class VEVENT_List(generics.ListAPIView):
|
|
|
|
"""
|
|
API endpoint that allows groups to be viewed or edited.
|
|
"""
|
|
# queryset = VEVENT.objects.all()
|
|
serializer_class = VEVENT_Serializer
|
|
|
|
def get_queryset(self):
|
|
"""
|
|
Optionally restricts the returned purchases to a given user,
|
|
by filtering against a `username` query parameter in the URL.
|
|
"""
|
|
queryset = VEVENT.objects.all()
|
|
queryset = VEVENT.objects.all()
|
|
start = self.request.query_params.get('start', None)
|
|
end = self.request.query_params.get('end', None)
|
|
if start is not None and end is not None:
|
|
queryset = queryset.filter(DTSTART__range=(start, end)).filter(mode__gt=100)
|
|
return queryset
|
|
|
|
|
|
|
|
|
|
class NHIOrderList(ListView):
|
|
model = NHIOrder
|
|
paginate_by = 25
|
|
|
|
# context_object_name = 'my_book_list' # your own name for the list as a template variable
|
|
# queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
|
|
# template_name = 'books/my_arbitrary_template_name_list.html' # Specify your own template name/location
|
|
|
|
# class MyDatatable(Datatable):
|
|
# model = NHIOrder
|
|
# class Meta:
|
|
# exclude = ['id', 'timestamp', 'updated']
|
|
|
|
# class NHIOrderDatatableView(DatatableView):
|
|
# model = NHIOrder
|
|
|
|
# datatable_class = MyDatatable
|
|
|
|
# Args: (<NHIOrder: NHIOrder object (3938132_2020-08-27)>,)
|
|
# Kwargs: {'default_value': '', 'rich_value': '', 'localize': False, 'datatable': <ck.views.datatable_class_Synthesized object at 0x7fb5ddb10730>, 'view': <ck.views.NHIOrderDatatableView object at 0x7fb5ddb39250>
|
|
|
|
# <a class="editable editable-click editable-empty" href="#" data-name="ApplyDoctor" data-pk="0950575_2020-12-23" data-placeholder="" data-source="/abcd" data-sourceoptions="{'data': {'param': 123}}" data-type="select" data-url="/pre-case/" data-value="" data-xeditable="xeditable">Empty</a>
|
|
|
|
|
|
|
|
# @cache
|
|
def AllDoctors(NhiDeptName):
|
|
|
|
# if NhiDeptName == '放射腫瘤科':
|
|
# dr, count = zip(*list(Treatment.objects.values_list("oncologist__name").annotate(Count("id")).order_by('-id__count')))
|
|
# dr2 = Oncologist.objects.values_list('name', flat=True)
|
|
# else:
|
|
# dr, count = zip(*list(Treatment.objects.values_list("surgeon__name").annotate(Count("id")).order_by('-id__count')))
|
|
# dr2 = Surgeon.objects.values_list('name', flat=True)
|
|
# return list(dr) + [d for d in list(dr2) if d not in dr]
|
|
|
|
dr, count = zip(*list(Treatment.objects.values_list("oncologist__name").annotate(Count("id")).order_by('-id__count')))
|
|
dr2 = Oncologist.objects.values_list('name', flat=True)
|
|
onco = list(dr) + [d for d in list(dr2) if d not in dr]
|
|
|
|
dr, count = zip(*list(Treatment.objects.values_list("surgeon__name").annotate(Count("id")).order_by('-id__count')))
|
|
dr2 = Surgeon.objects.values_list('name', flat=True)
|
|
surg = list(dr) + [d for d in list(dr2) if d not in dr]
|
|
|
|
if NhiDeptName == '放射腫瘤科':
|
|
return [d for d in onco+surg if d is not None]
|
|
|
|
return [d for d in surg+onco if d is not None]
|
|
|
|
|
|
@cache
|
|
def DoctorOptionByChartNo(ChartNo,NhiDeptName):
|
|
all = AllDoctors(NhiDeptName)
|
|
|
|
# records = portal.PatientMedicalRecordListQuery(ChartNo)
|
|
# records = records['Emergency']+records['InPat']+records['OutPat']
|
|
# # print(records)
|
|
|
|
# doctors = set()
|
|
# for record in records:
|
|
# MainDrName = record['MainDrName']
|
|
# if MainDrName is not None:
|
|
# MainDrName = MainDrName.replace('\ue09b', '峰') #'許峰銘'
|
|
# doctors.add(MainDrName)
|
|
|
|
# # print(doctors)
|
|
|
|
# # print(all)
|
|
# # print(doctors)
|
|
# intersect = [x for x in all if x in doctors]
|
|
|
|
# if not intersect:
|
|
# intersect = all
|
|
|
|
res = []
|
|
|
|
for d in all:
|
|
res.append({'value': d, 'text': d})
|
|
|
|
# res = [{'value': 1, 'text': "text1"}, {'value': 2, 'text': "text2"}]
|
|
|
|
return JsonResponse(res, safe=False)
|
|
|
|
|
|
# [{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]
|
|
def DoctorOption(request):
|
|
|
|
id = request.GET.get('id', '')
|
|
data = NHIOrder.objects.get(id=id)
|
|
return DoctorOptionByChartNo(data.ChartNo,data.NhiDeptName)
|
|
|
|
def GetDoctorByCode(code):
|
|
# print(f'--{code}--')
|
|
dr = Surgeon.objects.filter(staff_code=code).first()
|
|
if dr:
|
|
return dr
|
|
dr = Oncologist.objects.filter(staff_code=code).first()
|
|
if dr:
|
|
return dr
|
|
return None
|
|
|
|
|
|
class NHIOrderDatatableView(XEditableDatatableView):
|
|
model = NHIOrder
|
|
|
|
def filter_queryset(self, qs):
|
|
print(123)
|
|
|
|
def get_queryset(self):
|
|
|
|
order = None
|
|
|
|
ChartNo = self.request.GET.get('ChartNo')
|
|
own = self.request.GET.get('own')
|
|
if (ChartNo is not None) and len(ChartNo) > 1:
|
|
if own is not None:
|
|
PackageTime = datetime.datetime.today().strftime('%Y-%m-%d')
|
|
id = ChartNo+'_'+PackageTime[:7]
|
|
order = NHIOrder.objects.filter(id=id).first()
|
|
|
|
if order is None:
|
|
pat = portal.QueryModifyPatBase({'ChartNo': ChartNo})
|
|
print(pat)
|
|
order = NHIOrder()
|
|
order.ChartNo = ChartNo
|
|
order.PackageTime = datetime.datetime.today().strftime('%Y-%m-%d')
|
|
order.id = order.ChartNo+'_'+order.PackageTime[:7]
|
|
order.PatientName = pat['ChtName']
|
|
order.ApplyTypeDesc = '自費'
|
|
order.Priority = 1
|
|
order.save()
|
|
|
|
NHIOrder_id = self.request.GET.get('NHIOrder')
|
|
if NHIOrder_id is not None:
|
|
order = NHIOrder.objects.get(id=NHIOrder_id)
|
|
|
|
if order is not None:
|
|
dr = GetDoctorByCode(self.request.user.username)
|
|
if dr is not None:
|
|
order.ApplyDoctor = dr.name
|
|
order.save()
|
|
|
|
queryset = super().get_queryset()
|
|
|
|
if self.request.user.is_staff:
|
|
# if self.request.GET.get('search[value]')=="None":
|
|
# return NHIOrder.objects.filter(ApplyDoctor__isnull=True)
|
|
return queryset
|
|
|
|
# print(self.request.user)
|
|
# print(self.request.user.is_staff)
|
|
|
|
dr = GetDoctorByCode(self.request.user.username)
|
|
# print(dr)
|
|
if dr:
|
|
return queryset.filter(ApplyDoctor=dr.name)
|
|
|
|
|
|
return queryset.none()
|
|
return queryset.filter(**self.request.GET.dict())
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
# Call the base implementation first to get a context
|
|
context = super().get_context_data(**kwargs)
|
|
# Add in the publisher
|
|
# context['publisher'] = self.publisher
|
|
|
|
qs = NHIOrder.objects.filter(Priority__gt=0)
|
|
context['total'] = qs.count()
|
|
# context['waiting_list'] = NHIOrder.objects.filter(Priority__gt=0).values('ApplyDoctor').annotate(count=Count('ApplyDoctor')).order_by('-count')
|
|
context['waiting_list'] = qs.values('ApplyDoctor').annotate(count=Count('*')).order_by('-count')
|
|
|
|
|
|
|
|
if self.request.GET.get('refresh') is not None:
|
|
SortNHI(CheckTreated=False)
|
|
|
|
|
|
# context['ChartNo'] = self.request.GET.get('ChartNo')
|
|
NHIOrder_id = self.request.GET.get('NHIOrder')
|
|
if NHIOrder_id:
|
|
context['search'] = NHIOrder_id.split('_')[0]
|
|
|
|
ChartNo = self.request.GET.get('ChartNo')
|
|
if ChartNo:
|
|
context['search'] = ChartNo
|
|
|
|
return context
|
|
|
|
class datatable_class(Datatable):
|
|
|
|
# search for Empty ApplyDoctor
|
|
def search(self, queryset):
|
|
if 'None' in self.config['search']:
|
|
return queryset.filter(ApplyDoctor__isnull=True,Priority__gt=0)
|
|
return super().search(queryset)
|
|
|
|
def ProcessQuantity(self, *args, **kwargs):
|
|
# print(f' Args: {args}' )
|
|
# print(f' Kwargs: {kwargs}' )
|
|
|
|
data = args[0]
|
|
|
|
default_value = kwargs['default_value']
|
|
|
|
title = ''
|
|
|
|
if data.Reason:
|
|
title += data.Reason+' '
|
|
|
|
if data.ExamineReasonDesc:
|
|
title += data.ExamineReasonDesc
|
|
|
|
if title:
|
|
return f'{default_value}<i class="fa fa-info-circle" title="{title}"></i>'
|
|
|
|
return f'{default_value}'
|
|
|
|
|
|
if ExamineReasonDesc is None:
|
|
# return f'{default_value}<span class="material-icons" title="{data.Reason}">info</span>'
|
|
return f'{default_value}<i class="fa fa-info-circle" title="{data.Reason}"></i>'
|
|
|
|
return f'{default_value}<i class="fa fa-info-circle" title="{data.ExamineReasonDesc}"></i>'
|
|
|
|
def ProcessDiagnosis(self, *args, **kwargs):
|
|
data = args[0]
|
|
default_value = kwargs['default_value']
|
|
title = ''
|
|
|
|
# print(f'-{default_value}-')
|
|
|
|
# if default_value:
|
|
|
|
icd10 = ICD10CMfinal.objects.filter(ICD10CM=default_value).first()
|
|
if icd10 is not None:
|
|
title = icd10.ICD10CM_Chinese
|
|
|
|
# return f'{default_value}<span class="glyphicon glyphicon-info-sign" title="{title}"></span>'
|
|
return f'{default_value} {title}'
|
|
|
|
|
|
PriorityStyle = {
|
|
1: 'background:red',
|
|
2: 'background:yellow',
|
|
3: 'background:green',
|
|
4: 'background:white',
|
|
'': '',
|
|
}
|
|
|
|
def ProcessPriority(self, *args, **kwargs):
|
|
data = args[0]
|
|
default_value = kwargs['default_value']
|
|
|
|
# if default_value== is None or :
|
|
# style = ""
|
|
# else:
|
|
style = PriorityStyle[default_value]
|
|
|
|
# return '''
|
|
# <a href="#" data-name="Priority" data-pk="%s" data-placeholder=""
|
|
# data-source="[{value: 1, text: '1'}, {value: 2, text: '2'}]"
|
|
# data-type="select" data-url="/pre-case/" data-value="1" data-xeditable="xeditable" class="editable editable-click" data-original-title="" title="">%s</a>
|
|
# ''' % (data.id, default_value)
|
|
|
|
# data-source="[{value: 1}, {value: 2}, {value: 3}, {value: 4}]"
|
|
|
|
return '''
|
|
<a href="#" data-name="Priority" data-pk="%s" data-placeholder=""
|
|
data-source="[{value: 1, text: '1'}, {value: 2, text: '2'}, {value: 3, text: '3'}]"
|
|
data-type="select" data-url="/pre-case/" data-value="%s" data-xeditable="xeditable" class="editable editable-click" data-original-title="" title=""
|
|
style="%s"
|
|
>%s</a>
|
|
''' % (data.id, default_value, style, default_value)
|
|
|
|
|
|
def ProcessChartNo(self, *args, **kwargs):
|
|
data = args[0]
|
|
default_value = kwargs['default_value']
|
|
return f'''
|
|
<a class="editable-click" href="{reverse('patient-search')}?q={default_value}">{default_value}</a>
|
|
'''
|
|
|
|
|
|
def ProcessPatientName(self, *args, **kwargs):
|
|
data = args[0]
|
|
default_value = kwargs['default_value']
|
|
return f'''
|
|
<a class="editable-click" href="{reverse('patient-search')}?q={data.ChartNo}">{default_value}</a>
|
|
'''
|
|
|
|
def DoctorSelect(self, *args, **kwargs):
|
|
# print(f' Args: {args}' )
|
|
# print(f' Kwargs: {kwargs}' )
|
|
|
|
data = args[0]
|
|
default_value = kwargs['default_value']
|
|
|
|
# if default_value=="":
|
|
# default_value = "zzz"
|
|
|
|
# print('---',default_value,'---')
|
|
|
|
# XEditableDatatableView will fix the css class and empty text later
|
|
|
|
if kwargs['view'].request.user.is_staff:
|
|
return '''
|
|
<a href="#" data-name="ApplyDoctor"
|
|
data-pk="%s" data-placeholder="" data-source="/DoctorOption?id=%s" data-sourceCache="false"
|
|
data-sourceoptions='{"data": {"id": "%s"}}' data-type="select" data-url="/pre-case/" data-value="%s"
|
|
data-xeditable="xeditable">%s</a>
|
|
''' % (data.id, data.id, data.id, default_value, default_value)
|
|
else:
|
|
return default_value
|
|
|
|
class Meta:
|
|
# exclude = ['id', 'timestamp', 'updated', '', '']
|
|
|
|
|
|
columns = [
|
|
'ChartNo',
|
|
'PatientName',
|
|
'ApplyTypeDesc',
|
|
'StatusDesc',
|
|
'PackageTime',
|
|
'OrderCode',
|
|
# 'OrderName',
|
|
# 'ResultDesc',
|
|
'Quantity',
|
|
'ExamineQuantity',
|
|
'ExamineDate',
|
|
|
|
'Diagnosis',
|
|
'other_diagnosis',
|
|
'num_sessions',
|
|
|
|
'NhiDeptName',
|
|
'MainDrName',
|
|
'ApplyDoctor',
|
|
# 'ExamineReasonDesc',
|
|
|
|
'Priority',
|
|
'Memo',
|
|
]
|
|
|
|
ordering = ['-Priority', 'PackageTime']
|
|
|
|
processors = {
|
|
# 'ChartNo': 'ProcessChartNo',
|
|
# 'PatientName': ProcessPatientName,
|
|
'Quantity': 'ProcessQuantity',
|
|
'Diagnosis': 'ProcessDiagnosis',
|
|
'other_diagnosis': helpers.make_xeditable(),
|
|
'num_sessions': helpers.make_xeditable(),
|
|
'ApplyDoctor': 'DoctorSelect',
|
|
|
|
# 'Priority': helpers.make_xeditable(type='select',
|
|
# source='[{value: 1, text: "1"}, {value: 2, text: "2"}, {value: 3, text: "3"}]'
|
|
# ),
|
|
|
|
'Priority': helpers.make_xeditable(),
|
|
'Memo': helpers.make_xeditable(),
|
|
|
|
|
|
}
|
|
|
|
structure_template = "datatableview/bootstrap_structure.html"
|
|
|
|
def pre_add(request):
|
|
ChartNo = request.GET.get('ChartNo')
|
|
|
|
### A little bit too slow?
|
|
if False and (ChartNo is not None) and len(ChartNo) > 1:
|
|
for case in portal.QueryCaseByChartNo(ChartNo):
|
|
print(case)
|
|
UpdateNHICase(case)
|
|
|
|
nhiorders = NHIOrder.objects.filter(ChartNo=ChartNo)
|
|
context = {
|
|
'ChartNo': ChartNo,
|
|
'nhiorders': nhiorders,
|
|
}
|
|
|
|
if not nhiorders:
|
|
pat = portal.QueryModifyPatBase({'ChartNo': ChartNo,})
|
|
|
|
context['pat']=pat
|
|
|
|
template = loader.get_template('ck/nhiorder_add.html')
|
|
return HttpResponse(template.render(context, request))
|
|
|
|
class LesionCreate(CreateView):
|
|
# model = Lesion
|
|
form_class = LesionForm
|
|
template_name = 'ck/lesion_form.html'
|
|
|
|
# Need this to set treatment_id
|
|
def form_valid(self, form):
|
|
# lesion = form.save(commit=False)
|
|
# lesion.treatment_id = self.kwargs.get('treatment_id')
|
|
#article.save() # This is redundant, see comments.
|
|
form.instance.treatment_id = self.kwargs['treatment_id']
|
|
return super().form_valid(form)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["treatment"] = get_object_or_404(Treatment, pk=self.kwargs.get('treatment_id'))
|
|
return context
|
|
|
|
|
|
class LesionUpdate(UpdateView):
|
|
model = Lesion
|
|
form_class = LesionForm
|
|
|
|
class LesionDelete(DeleteView):
|
|
model = Lesion
|
|
|
|
# success_url = reverse_lazy('treatment-detail')
|
|
def get_success_url(self):
|
|
# Assuming there is a ForeignKey from Comment to Post in your model
|
|
return reverse_lazy( 'treatment-detail', kwargs={'object_id': self.object.treatment_id})
|
|
|
|
|
|
def CalendarIndex(request):
|
|
if request.GET.get('download') is not None:
|
|
QueryMS()
|
|
context={}
|
|
return render(request, 'calendar/index.html', context)
|
|
|