-
Piotr Gawron authoredPiotr Gawron authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
models.py 17.17 KiB
from __future__ import unicode_literals
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User, AnonymousUser
import datetime
from datetime import timedelta
def get_current_year():
return datetime.datetime.now().year
class Location (models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return "%s" % (self.name)
def __unicode__(self):
return "%s" % (self.name)
class Language (models.Model):
name = models.CharField(max_length=20)
image = models.ImageField()
def __str__(self):
return self.name
def image_img(self):
if self.image:
return u'<img class="flag-icon" src="%s" />' % (self.image.url)
else:
return 'No image'
image_img.short_description = 'Flag icon'
image_img.allow_tags = True
class Subject(models.Model):
SEX_CHOICES_MALE = 'M'
SEX_CHOICES_FEMALE = 'F'
SEX_CHOICES = (
(SEX_CHOICES_MALE,'Male'),
(SEX_CHOICES_FEMALE,'Female'),
)
SUBJECT_TYPE_CHOICES_CONTROL = 'C'
SUBJECT_TYPE_CHOICES = (
(SUBJECT_TYPE_CHOICES_CONTROL,'CONTROL'),
('P','PATIENT'),
)
def finish_all_visits(self):
visits = Visit.objects.filter(subject = self, is_finished = False)
for visit in visits:
visit.is_finished = True
visit.save()
def finish_all_appointments(self):
appointments = Appointment.objects.filter(visit__subject = self, status = Appointment.APPOINTMENT_STATUS_SCHEDULED)
for appointment in appointments:
appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
appointment.save()
def mark_as_dead(self):
self.dead = True
self.save()
self.finish_all_visits()
self.finish_all_appointments()
def mark_as_rejected(self):
self.resigned = True
self.save()
self.finish_all_visits()
self.finish_all_appointments()
sex = models.CharField(max_length=1,
choices=SEX_CHOICES,
verbose_name='Sex'
)
type = models.CharField(max_length=1,
choices=SUBJECT_TYPE_CHOICES,
verbose_name='Type'
)
dead = models.BooleanField(
verbose_name='Dead',
default= False,
editable=False
)
resigned = models.BooleanField(
verbose_name='Resigned',
default= False,
editable=False
)
default_location = models.ForeignKey(Location,
verbose_name='Default appointment location',
)
first_name = models.CharField(max_length=50,
verbose_name='First name'
)
last_name = models.CharField(max_length=50,
verbose_name='Last name'
)
languages = models.ManyToManyField(Language,
blank=True,
verbose_name='Known languages'
)
default_written_communication_language = models.ForeignKey(Language,
null=True,
blank=True,
related_name="%(class)s_written_comunication",
verbose_name='Default language for document generation'
)
phone_number = models.CharField(max_length=20,
null=True,
blank=True,
verbose_name='Phone number'
)
phone_number_2 = models.CharField(max_length=20,
null=True,
blank=True,
verbose_name='Phone number 2'
)
phone_number_3 = models.CharField(max_length=20,
null=True,
blank=True,
verbose_name='Phone number 3'
)
email = models.EmailField(
null=True,
blank=True,
verbose_name='E-mail'
)
date_born = models.DateField(
null=True,
blank=True,
verbose_name='Date of birth (YYYY-MM-DD)'
)
address = models.CharField(max_length=255,
blank=True,
verbose_name='Address'
)
postal_code = models.CharField(max_length=7,
blank=True,
verbose_name='Postal code'
)
city = models.CharField(max_length=50,
blank=True,
verbose_name='City'
)
country = models.CharField(max_length=50,
verbose_name='Country'
)
screening_number = models.CharField(max_length=50,
unique=True,
verbose_name='Screening number'
)
nd_number = models.CharField(max_length=6,
blank=True,
verbose_name='ND number'
)
mpower_id = models.CharField(max_length=20,
blank=True,
verbose_name='MPower ID'
)
comments = models.TextField(max_length=2000,
blank=True,
verbose_name='Comments'
)
date_added = models.DateField(verbose_name='Added on',
auto_now=True
)
referral = models.CharField(max_length=128,
null=True,
blank=True,
verbose_name='Referred by'
)
diagnosis = models.CharField(max_length=128,
null=True,
blank=True,
verbose_name='Diagnosis'
)
year_of_diagnosis = models.IntegerField(
default=0,
null=True,
blank=True,
verbose_name='Year of diagnosis (YYYY)'
)
def latest_visit(self):
visits = self.visit_set.all()
if len(visits)==0:
return None
result = visits[0];
for visit in visits:
if (visit.datetime_begin > result.datetime_begin):
result = visit
return result
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)
class Item (models.Model):
is_fixed = models.BooleanField(
default=False,
verbose_name='Is the item fixed?'
)
name = models.CharField(max_length=255,
verbose_name='Name'
)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Room (models.Model):
equipment = models.ManyToManyField(Item,
verbose_name='On-site equipment',
blank=True
)
owner = models.CharField(max_length=50,
verbose_name='Owner'
)
address = models.CharField(max_length=255,
verbose_name='Address'
)
city = models.CharField(max_length=50,
verbose_name='City'
)
room_number = models.IntegerField(
verbose_name='Room number'
)
floor = models.IntegerField(
verbose_name='Floor'
)
is_vehicle = models.BooleanField(
verbose_name='Is a vehicle?'
)
def __str__(self):
return "%d %s %s" % (self.room_number, self.address, self.city)
def __unicode__(self):
return "%d %s %s" % (self.room_number, self.address, self.city)
class AppointmentType (models.Model):
DEFAULT_COLOR = '#cfc600'
DEFAULT_FONT_COLOR = '#00000'
required_equipment = models.ManyToManyField(Item,
verbose_name='Required equipment',
blank = True
)
code = models.CharField(max_length=20,
verbose_name='Appointment code'
)
description = models.CharField(max_length=2000,
verbose_name='Appointment description'
)
default_duration = models.IntegerField(
verbose_name='Default duration (in minutes)'
)
calendar_color_priority = models.IntegerField(
verbose_name='Calendar color priority',
default=1
)
calendar_color = models.CharField(max_length=2000,
verbose_name='Calendar color',
default=DEFAULT_COLOR
)
calendar_font_color = models.CharField(max_length=2000,
verbose_name='Calendar color',
default=DEFAULT_FONT_COLOR
)
rest_time = models.IntegerField(
verbose_name='Suggested rest time',
default=0
)
REQ_ROLE_CHOICES = (
('DOCTOR', 'Doctor'),
('NURSE', 'Nurse'),
('PSYCHOLOGIST', 'Psychologist'),
('ANY', 'Any')
)
required_worker = models.CharField(max_length=20, choices=REQ_ROLE_CHOICES,
verbose_name='Type of worker required for appointment',
default='ANY'
)
def __str__(self):
return self.code
def __unicode__(self):
return self.code
class Worker (models.Model):
languages = models.ManyToManyField(Language,
verbose_name='Known languages'
)
locations = models.ManyToManyField(Location,
verbose_name='Locations'
)
appointments = models.ManyToManyField('Appointment', blank=True,
verbose_name='Appointments'
)
user = models.OneToOneField(User, blank=True, null=True,
verbose_name='Username'
)
first_name = models.CharField(max_length=50,
verbose_name='First name'
)
last_name = models.CharField(max_length=50,
verbose_name='Last name'
)
phone_number = models.CharField(max_length=20,
verbose_name='Phone number'
)
unit = models.CharField(max_length=50,
verbose_name='Unit'
)
email = models.EmailField(
verbose_name='E-mail'
)
ROLE_CHOICES_SECRETARY = "SECRETARY"
ROLE_CHOICES = (
('DOCTOR', 'Doctor'),
('NURSE', 'Nurse'),
('PSYCHOLOGIST', 'Psychologist'),
('TECHNICIAN', 'Technician'),
(ROLE_CHOICES_SECRETARY, 'Secretary')
)
role = models.CharField(max_length=20, choices=ROLE_CHOICES,
verbose_name='Role'
)
specialization = models.CharField(max_length=20,
verbose_name='Specialization'
)
def is_on_leave(self):
if len(self.holiday_set.filter(datetime_end__gt=datetime.datetime.now(),
datetime_start__lt=datetime.datetime.now())):
return True
return False
@staticmethod
def get_details(the_user):
if the_user.is_authenticated == False:
return ('Guest', 'Test account')
person = Worker.objects.filter(user=the_user)
if len(person) == 0:
return (the_user.get_full_name(), '<No worker information>')
else:
# For get_*_display, see:
# https://docs.djangoproject.com/en/1.10/topics/db/models/#field-options
return (str(person[0]), person[0].get_role_display())
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)
class FlyingTeam(models.Model):
# doctor = models.ForeignKey(Worker, related_name='FlyingTeamDoctor',
# verbose_name='Doctor'
# )
# nurse = models.ForeignKey(Worker, related_name='FlyingTeamNurse',
# verbose_name='Nurse'
# )
# psychologist = models.ForeignKey(Worker, related_name='FlyingTeamPsychologist',
# verbose_name='Psychologist'
# )
# datetime_called = models.DateTimeField(
# verbose_name='Created on'
# )
# datetime_until = models.DateTimeField(
# verbose_name='Disbanded on'
# )
#
# def __str__(self):
# return "%s %s %s" % (self.doctor.last_name, self.nurse.last_name, self.psychologist.last_name)
#
# def __unicode__(self):
# return "%s %s %s" % (self.doctor.last_name, self.nurse.last_name, self.psychologist.last_name)
place = models.CharField(max_length=50,
verbose_name='Place',
)
def __str__(self):
return "%s" % (self.place)
def __unicode__(self):
return "%s" % (self.place)
class Avaibility(models.Model):
person = models.ForeignKey(Worker, on_delete=models.CASCADE,
verbose_name='Worker'
)
day_number = models.IntegerField(
verbose_name='Day of the week'
)
available_from = models.TimeField(
verbose_name='Avaible since'
)
available_till = models.TimeField(
verbose_name='Avaible until'
)
is_current = models.BooleanField(
verbose_name='Is current?',
default=True
)
def __str__(self):
return "%d %s %s" % (self.day_number, self.person.last_name, self.person.first_name)
def __unicode__(self):
return "%d %s %s" % (self.day_number, self.person.last_name, self.person.first_name)
class Holiday(models.Model):
person = models.ForeignKey(Worker, on_delete=models.CASCADE,
verbose_name='Worker'
)
datetime_start = models.DateTimeField(
verbose_name='On leave since'
)
datetime_end = models.DateTimeField(
verbose_name='On leave until'
)
def __str__(self):
return "%s %s" % (self.person.first_name, self.person.last_name)
def __unicode__(self):
return "%s %s" % (self.person.first_name, self.person.last_name)
class Visit(models.Model):
subject = models.ForeignKey(Subject, on_delete=models.CASCADE,
verbose_name='Subject'
)
datetime_begin = models.DateTimeField(
verbose_name='Visit starts at'
)
datetime_end = models.DateTimeField(
verbose_name='Visit ends at'
) # Deadline before which all appointments need to be scheduled
is_finished = models.BooleanField(
verbose_name='Has ended',
default=False
)
appointment_types = models.ManyToManyField(AppointmentType,
verbose_name='Requested appointments',
blank=True,
)
def __unicode__(self):
return "%s %s" % (self.subject.first_name, self.subject.last_name)
def __str__(self):
return "%s %s" % (self.subject.first_name, self.subject.last_name)
def follow_up_title(self):
count = Visit.objects.filter(subject=self.subject, datetime_begin__lt =self.datetime_begin).count()
return "Visit " + str(count + 1)
def mark_as_finished(self):
self.is_finished = True
self.save()
if (not self.subject.dead) and (not self.subject.resigned):
visit_started = self.datetime_begin
time_to_next_visit = datetime.timedelta(days=365)
if self.subject.type== Subject.SUBJECT_TYPE_CHOICES_CONTROL:
time_to_next_visit = datetime.timedelta(days=365*3+366)
Visit.objects.create(
subject = self.subject,
datetime_begin = visit_started+time_to_next_visit,
datetime_end = visit_started+time_to_next_visit+datetime.timedelta(days=93)
)
class Appointment(models.Model):
APPOINTMENT_STATUS_SCHEDULED = 'SCHEDULED';
APPOINTMENT_STATUS_FINISHED = 'FINISHED';
APPOINTMENT_STATUS_CANCELLED = 'CANCELLED';
APPOINTMENT_STATUS_NO_SHOW = 'NO_SHOW';
APPOINTMENT_STATUS_CHOICES = (
(APPOINTMENT_STATUS_SCHEDULED, 'Scheduled'),
(APPOINTMENT_STATUS_FINISHED, 'Finished'),
(APPOINTMENT_STATUS_CANCELLED, 'Cancelled'),
(APPOINTMENT_STATUS_NO_SHOW, 'No Show'),
)
flying_team = models.ForeignKey(FlyingTeam,
verbose_name='Flying team (if applicable)',
null=True, blank=True
)
worker_assigned = models.ForeignKey(Worker,
verbose_name='Worker conducting the assessment (if applicable)',
null=True, blank=True
)
appointment_types = models.ManyToManyField(AppointmentType,
verbose_name='Appointment types',
blank=True
)
room = models.ForeignKey(Room,
verbose_name='Room ID',
null=True,
blank=True
)
location = models.ForeignKey(Location,
verbose_name='Location',
)
visit = models.ForeignKey(Visit,
verbose_name='Visit ID'
)
comment = models.TextField(max_length=1024,
verbose_name='Comment',
null=True,
blank=True
)
datetime_when = models.DateTimeField(
verbose_name='Appointment on',
null=True, blank=True
)
length = models.IntegerField(
verbose_name='Appointment length (in minutes)'
)#Potentially redundant; but can be used to manually adjust appointment's length
status = models.CharField(max_length=20, choices=APPOINTMENT_STATUS_CHOICES,
verbose_name='Status',
editable=False,
default=APPOINTMENT_STATUS_SCHEDULED
)
def mark_as_finished(self):
self.status = Appointment.APPOINTMENT_STATUS_FINISHED
self.save()
def mark_as_cancelled(self):
self.status = Appointment.APPOINTMENT_STATUS_CANCELLED
self.save()
def mark_as_no_show(self):
self.status = Appointment.APPOINTMENT_STATUS_NO_SHOW
self.save()
def datetime_until(self):
if self.datetime_when is None:
return None
else:
return self.datetime_when + timedelta(minutes=max(self.length, 15))
def color(self):
result = AppointmentType.DEFAULT_COLOR
priority = 1000000
for type in self.appointment_types.all():
if type.calendar_color_priority<priority:
priority=type.calendar_color_priority
result = type.calendar_color
return result
def font_color(self):
result = AppointmentType.DEFAULT_FONT_COLOR
priority = 1000000
for type in self.appointment_types.all():
if type.calendar_color_priority<priority:
priority=type.calendar_color_priority
result = type.calendar_font_color
return result
def title(self):
if self.visit.subject.screening_number=="---":
return self.comment.replace("\n", ";").replace("\r", ";")
else:
title = self.visit.subject.first_name + " " + self.visit.subject.last_name + " type: "
for type in self.appointment_types.all():
title += type.code+", "
return title