# coding=utf-8 import logging import re from django.db import models from web.models import VoucherType, Appointment, Location, Visit from web.models.constants import BOOL_CHOICES, SUBJECT_TYPE_CHOICES, FILE_STORAGE logger = logging.getLogger(__name__) class StudySubject(models.Model): class Meta: app_label = 'web' 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_resigned(self): self.resigned = True self.finish_all_visits() self.finish_all_appointments() subject = models.ForeignKey("web.Subject", verbose_name='Subject', editable=False, null=False, ) study = models.ForeignKey("web.Study", verbose_name='Study', editable=False, null=False, ) postponed = models.BooleanField(choices=BOOL_CHOICES, verbose_name='Postponed', default=False ) datetime_contact_reminder = models.DateTimeField( null=True, blank=True, verbose_name='Please make a contact on', ) type = models.CharField(max_length=1, choices=SUBJECT_TYPE_CHOICES.items(), verbose_name='Type', null=True, blank=True ) default_location = models.ForeignKey(Location, verbose_name='Default appointment location', null=True, blank=True ) flying_team = models.ForeignKey("web.FlyingTeam", verbose_name='Default flying team location (if applicable)', null=True, blank=True ) screening_number = models.CharField(max_length=50, verbose_name='Screening number', blank=True, null=True ) nd_number = models.CharField(max_length=25, 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_add=True ) referral = models.CharField(max_length=128, null=True, blank=True, verbose_name='Referred by' ) referral_letter = models.FileField( storage=FILE_STORAGE, upload_to='referral_letters', verbose_name='Referral letter', blank=True, null=True, ) health_partner = models.ForeignKey("web.Worker", verbose_name='Health partner', null=True, blank=True ) health_partner_feedback_agreement = models.BooleanField( verbose_name='Agrees to give information to referral', default=False, ) screening = models.CharField(max_length=1024, null=True, blank=True, verbose_name='Screening' ) diagnosis = models.CharField(max_length=1024, null=True, blank=True, verbose_name='Diagnosis' ) previously_in_study = models.BooleanField( verbose_name='Previously in PDP study', default=False, ) voucher_types = models.ManyToManyField(VoucherType, blank=True, verbose_name='Voucher types' ) year_of_diagnosis = models.IntegerField( null=True, blank=True, verbose_name='Year of diagnosis (YYYY)' ) information_sent = models.BooleanField( verbose_name='Information sent', default=False ) pd_in_family = models.NullBooleanField( verbose_name='PD in family', default=None, ) resigned = models.BooleanField( verbose_name='Resigned', default=False, editable=True ) resign_reason = models.TextField(max_length=2000, blank=True, verbose_name='Resign reason' ) def sort_matched_screening_first(self, pattern, reverse=False): parts = self.screening_number.split(';') matches, reminder = [], [] for part in parts: chunks = part.strip().split('-') if len(chunks) == 2: letter, number = chunks tupl = (letter, int(number)) else: logger.warn('There are {} chunks in some parts of this screening_number: |{}|.'.format( len(chunks), self.screening_number)) tupl = (part.strip(), None) if pattern is not None and pattern in part: matches.append(tupl) else: reminder.append(tupl) return matches + sorted(reminder, reverse=reverse) @staticmethod def check_nd_number_regex(regex_str): nd_numbers = StudySubject.objects.all().values_list('nd_number', flat=True) regex = re.compile(regex_str) for nd_number in nd_numbers: if regex.match(nd_number) is None: return False return True def __str__(self): return "%s %s" % (self.subject.first_name, self.subject.last_name) def __unicode__(self): return "%s %s" % (self.subject.first_name, self.subject.last_name)