Skip to content
Snippets Groups Projects
Commit 95830ed5 authored by Carlos Vega's avatar Carlos Vega
Browse files

attempt to avoid the migrations issue in the CI

parent 3cf4389d
No related branches found
No related tags found
1 merge request!445Support for Python 3.11
...@@ -16,12 +16,13 @@ logger = logging.getLogger(__name__) ...@@ -16,12 +16,13 @@ logger = logging.getLogger(__name__)
class StudySubject(models.Model): class StudySubject(models.Model):
class Meta: class Meta:
app_label = 'web' app_label = "web"
@property @property
def provenances(self): def provenances(self):
return Provenance.objects.filter(modified_table=StudySubject._meta.db_table, return Provenance.objects.filter(
modified_table_id=self.id).order_by('-modification_date') modified_table=StudySubject._meta.db_table, modified_table_id=self.id
).order_by("-modification_date")
def finish_all_visits(self): def finish_all_visits(self):
visits = Visit.objects.filter(subject=self, is_finished=False) visits = Visit.objects.filter(subject=self, is_finished=False)
...@@ -30,8 +31,7 @@ class StudySubject(models.Model): ...@@ -30,8 +31,7 @@ class StudySubject(models.Model):
visit.save() visit.save()
def finish_all_appointments(self): def finish_all_appointments(self):
appointments = Appointment.objects.filter( appointments = Appointment.objects.filter(visit__subject=self, status=Appointment.APPOINTMENT_STATUS_SCHEDULED)
visit__subject=self, status=Appointment.APPOINTMENT_STATUS_SCHEDULED)
for appointment in appointments: for appointment in appointments:
appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
appointment.save() appointment.save()
...@@ -51,143 +51,92 @@ class StudySubject(models.Model): ...@@ -51,143 +51,92 @@ class StudySubject(models.Model):
self.finish_all_visits() self.finish_all_visits()
self.finish_all_appointments() self.finish_all_appointments()
subject = models.ForeignKey("web.Subject", subject = models.ForeignKey(
verbose_name='Subject', "web.Subject", verbose_name="Subject", editable=False, null=False, on_delete=models.CASCADE
editable=False, )
null=False, on_delete=models.CASCADE
) study = models.ForeignKey("web.Study", verbose_name="Study", editable=False, null=False, on_delete=models.CASCADE)
study = models.ForeignKey("web.Study", postponed = models.BooleanField(choices=BOOL_CHOICES, verbose_name="Postponed", default=False)
verbose_name='Study',
editable=False,
null=False, on_delete=models.CASCADE
)
postponed = models.BooleanField(choices=BOOL_CHOICES,
verbose_name='Postponed',
default=False
)
datetime_contact_reminder = models.DateTimeField( datetime_contact_reminder = models.DateTimeField(
null=True, null=True,
blank=True, blank=True,
verbose_name='Please make a contact on', verbose_name="Please make a contact on",
)
type = models.ForeignKey("web.SubjectType", null=False, blank=False, on_delete=models.PROTECT, verbose_name="Type")
visit_used_to_compute_followup_date = models.ForeignKey(
"web.Visit",
null=True,
on_delete=models.SET_NULL,
editable=False,
) )
type = models.ForeignKey("web.SubjectType", default_location = models.ForeignKey(
null=False, Location,
blank=False, verbose_name="Default appointment location",
on_delete=models.PROTECT, null=True,
verbose_name='Type' blank=True,
) on_delete=models.SET_NULL,
limit_choices_to={"removed": False},
visit_used_to_compute_followup_date = models.ForeignKey("web.Visit", )
null=True,
on_delete=models.SET_NULL, flying_team = models.ForeignKey(
editable=False, "web.FlyingTeam",
) verbose_name="Default flying team location (if applicable)",
null=True,
default_location = models.ForeignKey(Location, blank=True,
verbose_name='Default appointment location', on_delete=models.SET_NULL,
null=True, )
blank=True,
on_delete=models.SET_NULL, screening_number = models.CharField(max_length=50, verbose_name="Screening number", blank=True, null=True)
limit_choices_to={"removed": False} nd_number = models.CharField(
) max_length=25,
blank=True,
flying_team = models.ForeignKey("web.FlyingTeam", verbose_name="Subject number",
verbose_name='Default flying team location (if applicable)', )
null=True, comments = models.TextField(max_length=2000, blank=True, verbose_name="Comments")
blank=True, on_delete=models.SET_NULL 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")
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='Subject number',
)
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( referral_letter = models.FileField(
storage=FILE_STORAGE, storage=FILE_STORAGE,
upload_to='referral_letters', upload_to="referral_letters",
verbose_name='Referral letter', verbose_name="Referral letter",
blank=True, blank=True,
null=True, null=True,
) )
health_partner = models.ForeignKey("web.Worker", health_partner = models.ForeignKey(
verbose_name='Health partner', "web.Worker", verbose_name="Health partner", null=True, blank=True, on_delete=models.CASCADE
null=True, )
blank=True, on_delete=models.CASCADE
)
health_partner_feedback_agreement = models.BooleanField( health_partner_feedback_agreement = models.BooleanField(
verbose_name='Agrees to give information to referral', verbose_name="Agrees to give information to referral",
default=False, default=False,
) )
voucher_types = models.ManyToManyField(VoucherType, voucher_types = models.ManyToManyField(VoucherType, blank=True, verbose_name="Voucher types")
blank=True,
verbose_name='Voucher types'
)
information_sent = models.BooleanField( information_sent = models.BooleanField(verbose_name="Information sent", default=False)
verbose_name='Information sent',
default=False
)
resigned = models.BooleanField( resigned = models.BooleanField(verbose_name="Resigned", default=False, editable=True)
verbose_name='Resigned', resign_reason = models.TextField(max_length=2000, blank=True, verbose_name="Resign reason")
default=False, excluded = models.BooleanField(verbose_name="Excluded", default=False, editable=True)
editable=True exclude_reason = models.TextField(max_length=2000, blank=True, verbose_name="Exclude reason")
) endpoint_reached = models.BooleanField(verbose_name="Endpoint Reached", default=False, editable=True)
resign_reason = models.TextField(max_length=2000, endpoint_reached_reason = models.TextField(max_length=2000, blank=True, verbose_name="Endpoint reached comments")
blank=True,
verbose_name='Resign reason'
)
excluded = models.BooleanField(
verbose_name='Excluded',
default=False,
editable=True
)
exclude_reason = models.TextField(max_length=2000,
blank=True,
verbose_name='Exclude reason'
)
endpoint_reached = models.BooleanField(
verbose_name='Endpoint Reached',
default=False,
editable=True
)
endpoint_reached_reason = models.TextField(max_length=2000,
blank=True,
verbose_name='Endpoint reached comments'
)
def sort_matched_screening_first(self, pattern, reverse=False): def sort_matched_screening_first(self, pattern, reverse=False):
if self.screening_number is None: if self.screening_number is None:
return None return None
parts = self.screening_number.split(';') parts = self.screening_number.split(";")
matches, reminder = [], [] matches, reminder = [], []
try: try:
for part in parts: for part in parts:
chunks = part.strip().split('-') chunks = part.strip().split("-")
if len(chunks) == 2: if len(chunks) == 2:
letter, number = chunks letter, number = chunks
try: try:
...@@ -195,8 +144,11 @@ class StudySubject(models.Model): ...@@ -195,8 +144,11 @@ class StudySubject(models.Model):
except ValueError: # better than isdigit because isdigit fails with negative numbers and others except ValueError: # better than isdigit because isdigit fails with negative numbers and others
tupl = (letter, number) tupl = (letter, number)
else: else:
logger.warning('There are %d chunks in some parts of this screening_number: |%s|.', logger.warning(
len(chunks), self.screening_number) "There are %d chunks in some parts of this screening_number: |%s|.",
len(chunks),
self.screening_number,
)
tupl = (part.strip(), None) tupl = (part.strip(), None)
if pattern is not None and pattern in part: if pattern is not None and pattern in part:
matches.append(tupl) matches.append(tupl)
...@@ -209,8 +161,13 @@ class StudySubject(models.Model): ...@@ -209,8 +161,13 @@ class StudySubject(models.Model):
@staticmethod @staticmethod
def check_nd_number_regex(regex_str, study): def check_nd_number_regex(regex_str, study):
nd_numbers = StudySubject.objects.filter(study=study).exclude(nd_number__isnull=True).exclude( nd_numbers = (
nd_number__exact='').all().values_list('nd_number', flat=True) StudySubject.objects.filter(study=study)
.exclude(nd_number__isnull=True)
.exclude(nd_number__exact="")
.all()
.values_list("nd_number", flat=True)
)
regex = re.compile(regex_str) regex = re.compile(regex_str)
for nd_number in nd_numbers: for nd_number in nd_numbers:
if regex.match(nd_number) is None: if regex.match(nd_number) is None:
...@@ -223,15 +180,15 @@ class StudySubject(models.Model): ...@@ -223,15 +180,15 @@ class StudySubject(models.Model):
@property @property
def status(self): def status(self):
if self.subject.dead: if self.subject.dead:
return 'Deceased' return "Deceased"
elif self.resigned: elif self.resigned:
return 'Resigned' return "Resigned"
elif self.excluded: elif self.excluded:
return 'Excluded' return "Excluded"
elif self.endpoint_reached: elif self.endpoint_reached:
return 'Endpoint Reached' return "Endpoint Reached"
else: else:
return 'Normal' return "Normal"
@property @property
def custom_data_values(self): def custom_data_values(self):
...@@ -240,8 +197,9 @@ class StudySubject(models.Model): ...@@ -240,8 +197,9 @@ class StudySubject(models.Model):
for value in values: for value in values:
fields.remove(value.study_subject_field) fields.remove(value.study_subject_field)
for field in fields: for field in fields:
CustomStudySubjectValue.objects.create(study_subject=self, value=field.default_value, CustomStudySubjectValue.objects.create(
study_subject_field=field) study_subject=self, value=field.default_value, study_subject_field=field
)
return CustomStudySubjectValue.objects.filter(study_subject=self) return CustomStudySubjectValue.objects.filter(study_subject=self)
def set_custom_data_value(self, custom_study_subject_field: CustomStudySubjectField, value: str): def set_custom_data_value(self, custom_study_subject_field: CustomStudySubjectField, value: str):
...@@ -253,11 +211,14 @@ class StudySubject(models.Model): ...@@ -253,11 +211,14 @@ class StudySubject(models.Model):
existing_value.save() existing_value.save()
if not found: if not found:
self.customstudysubjectvalue_set.add( self.customstudysubjectvalue_set.add(
CustomStudySubjectValue.objects.create(study_subject=self, value=value, CustomStudySubjectValue.objects.create(
study_subject_field=custom_study_subject_field)) study_subject=self, value=value, study_subject_field=custom_study_subject_field
)
)
def __str__(self): def __str__(self):
return f"{self.subject.first_name} {self.subject.last_name}" # pylint: disable-next=C0209
return "%s %s" % (self.subject.first_name, self.subject.last_name)
def get_custom_data_value(self, custom_field: CustomStudySubjectField) -> Optional[CustomStudySubjectValue]: def get_custom_data_value(self, custom_field: CustomStudySubjectField) -> Optional[CustomStudySubjectValue]:
for value in self.custom_data_values: for value in self.custom_data_values:
...@@ -269,7 +230,7 @@ class StudySubject(models.Model): ...@@ -269,7 +230,7 @@ class StudySubject(models.Model):
for value in self.custom_data_values.all(): for value in self.custom_data_values.all():
if value.study_subject_field.name == param: if value.study_subject_field.name == param:
return value.value return value.value
return '' return ""
def set_custom_field_value(self, param: str, value: str): def set_custom_field_value(self, param: str, value: str):
for custom_value in self.custom_data_values.all(): for custom_value in self.custom_data_values.all():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment