class CrfModelMixin(CrfNoManagerModelMixin): on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords(inherit=True) class Meta(CrfNoManagerModelMixin.Meta): abstract = True
class FollowUp(ClinicalAssessmentModelMixin, CrfModelMixin): fluconazole_dose = models.CharField( verbose_name='Fluconazole dose (day prior to visit)', max_length=25, choices=FLUCONAZOLE_DOSE) fluconazole_dose_other = OtherCharField( verbose_name='If other, specify dose:', max_length=25) rifampicin_started = models.CharField( verbose_name='Rifampicin started since last visit?', max_length=25, choices=YES_NO_ALREADY_ND) rifampicin_start_date = models.DateField( verbose_name='Date Rifampicin started', validators=[date_not_future], null=True, blank=True, ) patient_help = models.CharField( verbose_name=('Does the patient require help from' ' anybody for everyday activities? '), max_length=10, choices=YES_NO_ND, help_text=('For example eating, drinking, washing,' ' brushing teeth, going to the toilet')) patient_problems = models.CharField( verbose_name= 'Has the illness left the patient with any other problems?', max_length=10, choices=YES_NO_ND) rankin_score = models.CharField(verbose_name='Modified Rankin score', choices=RANKIN_SCORE, max_length=10, null=True) other_significant_dx = models.CharField( verbose_name='Other significant diagnosis since last visit?', max_length=5, choices=YES_NO_NA) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Follow-up' verbose_name_plural = 'Follow-up'
class MedicalExpensesTwo(CrfModelMixin): on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Health Economics: Medical Expenses Part 2" verbose_name_plural = "Health Economics: Medical Expenses Part 2"
class EducationHoh(EducationModelMixin, CrfModelMixin): on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Health Economics: Education (Person who earns the highest income)' verbose_name_plural = 'Health Economics: Education (Person who earns the highest income)'
class Week16(CrfModelMixin): patient_alive = models.CharField(verbose_name="Is the patient alive?", max_length=15, choices=YES_NO_UNKNOWN) death_datetime = models.DateTimeField( verbose_name="If deceased, date and time of death", validators=[datetime_not_future], null=True, blank=True, help_text="Leave blank if date is unknown.", ) activities_help = models.CharField( verbose_name= ("Does the patient require help from anybody for everyday activities?" ), max_length=5, choices=YES_NO_NA, help_text=("For example eating, drinking, washing, brushing teeth, " "going to the toilet."), ) illness_problems = models.CharField( verbose_name= "Has the illness left the patient with any other problems?", max_length=5, choices=YES_NO_NA, ) rankin_score = models.CharField( verbose_name="Modified Rankin score", max_length=10, choices=RANKIN_SCORE, default=NOT_APPLICABLE, ) week16_narrative = models.TextField(verbose_name="Narrative", max_length=1000, null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Week 16" verbose_name_plural = "Week 16"
class CrfWithActionModelMixin( CrfNoManagerModelMixin, ActionNoManagersModelMixin, TrackingModelMixin, ): action_name = None tracking_identifier_prefix = "" on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords(inherit=True) class Meta(CrfNoManagerModelMixin.Meta): abstract = True
class Week4(ClinicalAssessmentModelMixin, CrfModelMixin): fluconazole_dose = models.CharField( verbose_name="Fluconazole dose (day prior to visit)", max_length=25, choices=FLUCONAZOLE_DOSE, ) fluconazole_dose_other = OtherCharField(max_length=25) rifampicin_started = models.CharField( verbose_name="Rifampicin started since last visit?", max_length=25, choices=YES_NO_ALREADY_ND, ) rifampicin_start_date = models.DateField( verbose_name="Date Rifampicin started", validators=[date_not_future], null=True, blank=True, ) lp_done = models.CharField( verbose_name="LP done?", max_length=5, choices=YES_NO, help_text="If yes, ensure LP CRF completed.", ) other_significant_dx = models.CharField( verbose_name="Other significant diagnosis since last visit?", max_length=5, choices=YES_NO_NA, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Week 4" verbose_name_plural = "Week 4"
class Week16(CrfModelMixin): patient_alive = models.CharField(verbose_name='Is the patient alive?', max_length=5, choices=YES_NO) death_datetime = models.DateTimeField( verbose_name='If dead, date and time of death', validators=[date_not_future], null=True, blank=True) activities_help = models.CharField( verbose_name= ('Does the patient require help from anybody for everyday activities?' ), max_length=5, choices=YES_NO_NA, help_text=('For example eating, drinking, washing, brushing teeth, ' 'going to the toilet.')) illness_problems = models.CharField( verbose_name= 'Has the illness left the patient with any other problems?', max_length=5, choices=YES_NO_NA) rankin_score = models.CharField(verbose_name='Modified Rankin score', max_length=10, choices=RANKIN_SCORE) week16_narrative = models.TextField(verbose_name='Narrative', max_length=1000, null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name_plural = 'Week16'
class Education(EducationModelMixin, CrfModelMixin): household_head = models.CharField( verbose_name='Are you the person who earns the highest income?', max_length=5, choices=YES_NO, help_text=('If NO, please complete the form "Health Economics: ' 'Education (Person who earns the highest income)" on behalf of the ' 'Person who earns the highest income.')) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Health Economics: Education' verbose_name_plural = 'Health Economics: Education'
class BloodResultsModelMixin( CrfNoManagerModelMixin, ActionModelMixin, TrackingModelMixin ): action_name = None results_abnormal = models.CharField( verbose_name="Are any of the above results abnormal?", choices=YES_NO, max_length=25, ) results_reportable = models.CharField( verbose_name="If any results are abnormal, are results within grade III " "or above?", max_length=25, choices=YES_NO_NA, help_text=( "If YES, this value will open Adverse Event Form.<br/><br/>" "Note: On Day 1 only abnormal bloods should not be reported as adverse" "events." ), ) summary = models.TextField(null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() def save(self, *args, **kwargs): # self.subject_identifier = self.subject_visit.subject_identifier self.summary = "\n".join(self.get_summary()) super().save(*args, **kwargs) def get_summary(self): registered_subject = RegisteredSubject.objects.get( subject_identifier=self.subject_visit.subject_identifier ) opts = dict( gender=registered_subject.gender, dob=registered_subject.dob, report_datetime=self.subject_visit.report_datetime, ) summary = [] for field in [f.name for f in self._meta.fields]: grp = site_reportables.get("meta").get(field) value = getattr(self, field) if value and grp: units = getattr(self, f"{field}_units") opts.update(units=units) grade = grp.get_grade(value, **opts) if grade and grade.grade: summary.append(f"{field}: {grade.description}.") elif not grade: normal = grp.get_normal(value, **opts) if not normal: summary.append(f"{field}: {value} {units} is abnormal") return summary def get_action_item_reason(self): return self.summary @property def abnormal(self): return self.results_abnormal @property def reportable(self): return self.results_reportable class Meta(CrfNoManagerModelMixin.Meta): abstract = True
class LumbarPunctureCsf(CrfModelMixin, BiosynexSemiQuantitativeCragMixin): lp_datetime = models.DateTimeField(verbose_name="LP Date and Time", validators=[datetime_not_future]) qc_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="qcrequisition", verbose_name="QC Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) qc_assay_datetime = models.DateTimeField( verbose_name="QC Result Report Date and Time", validators=[datetime_not_future], blank=True, null=True, ) csf_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="csfrequisition", verbose_name="CSF Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) csf_assay_datetime = models.DateTimeField( verbose_name="CSF Result Report Date and Time", validators=[datetime_not_future], null=True, blank=True, ) reason_for_lp = models.CharField(verbose_name="Reason for LP", max_length=50, choices=LP_REASON) opening_pressure = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(99)], help_text=mark_safe("Units cm of H<sub>2</sub>O"), ) closing_pressure = models.IntegerField( blank=True, null=True, validators=[MinValueValidator(0), MaxValueValidator(99)], help_text=mark_safe("Units cm of H<sub>2</sub>O"), ) csf_amount_removed = models.IntegerField( blank=True, null=True, verbose_name="CSF amount removed ", validators=[MinValueValidator(1)], help_text="Units ml", ) quantitative_culture = models.IntegerField( blank=True, null=True, validators=[MinValueValidator(0), MaxValueValidator(100_000_000)], help_text="Units CFU/ml", ) csf_culture = models.CharField( verbose_name="Other organism (non-Cryptococcus)", max_length=18, choices=YES_NO_NOT_DONE_WAIT_RESULTS, default=AWAITING_RESULTS, help_text="Complete after getting the results.", ) other_csf_culture = models.CharField( verbose_name="If YES, specify organism:", max_length=75, blank=True, null=True) csf_wbc_cell_count = models.IntegerField( verbose_name="Total CSF WBC cell count:", help_text=mark_safe(f"acceptable units are {MM3_DISPLAY}"), validators=[MinValueValidator(0)], null=True, blank=True, ) differential_lymphocyte_count = models.IntegerField( verbose_name="Differential lymphocyte cell count:", validators=[MinValueValidator(0)], blank=True, null=True, help_text=mark_safe(f"acceptable units are {MM3_DISPLAY} or %"), ) differential_lymphocyte_unit = models.CharField(choices=MM3_PERC_UNITS, max_length=6, null=True, blank=True) differential_neutrophil_count = models.IntegerField( verbose_name="Differential neutrophil cell count:", validators=[MinValueValidator(0)], blank=True, null=True, help_text=mark_safe(f"acceptable units are {MM3_DISPLAY} or %"), ) differential_neutrophil_unit = models.CharField(choices=MM3_PERC_UNITS, max_length=6, null=True, blank=True) india_ink = models.CharField(max_length=15, choices=POS_NEG, null=True, blank=True) csf_glucose = models.DecimalField( verbose_name="CSF glucose:", decimal_places=1, max_digits=3, blank=True, null=True, help_text= f"Units in {MILLIMOLES_PER_LITER} or {MILLIGRAMS_PER_DECILITER}", ) csf_glucose_units = models.CharField( verbose_name="CSF glucose units:", max_length=6, choices=MG_MMOL_UNITS, blank=True, null=True, ) csf_protein = models.DecimalField( verbose_name="CSF protein:", decimal_places=2, max_digits=4, blank=True, null=True, help_text=f"Units in {GRAMS_PER_LITER}", ) csf_cr_ag = models.CharField(verbose_name="CSF CrAg:", max_length=15, choices=POS_NEG, blank=True, null=True) csf_cr_ag_lfa = models.CharField( verbose_name="CSF CrAg done by IMMY CrAg LFA:", max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Lumbar Puncture/Cerebrospinal Fluid" verbose_name_plural = "Lumbar Puncture/Cerebrospinal Fluid"
class FollowUp(ClinicalAssessmentModelMixin, CrfModelMixin): fluconazole_dose = models.CharField( verbose_name="Fluconazole dose (day prior to visit)", max_length=25, choices=FLUCONAZOLE_DOSE, ) fluconazole_dose_other = OtherCharField( verbose_name="If other, specify dose:", max_length=25) rifampicin_started = models.CharField( verbose_name="Rifampicin started since last visit?", max_length=25, choices=YES_NO_ALREADY_ND, ) rifampicin_start_date = models.DateField( verbose_name="Date Rifampicin started", validators=[date_not_future], null=True, blank=True, ) days_hospitalized = models.DecimalField( verbose_name=("Over the ten weeks spent in the study how " "many days did the patient spend in hospital?"), decimal_places=3, max_digits=5, null=True, ) antibiotic = models.ManyToManyField( Antibiotic, blank=True, verbose_name="Were any of the following antibiotics given?", ) antibiotic_other = models.CharField( verbose_name="If other antibiotics, please specify:", max_length=50, null=True, blank=True, ) blood_transfusions = models.CharField( verbose_name= "Has the patient had any blood transfusions since week two? ", max_length=5, choices=YES_NO, null=True, ) blood_transfusions_units = models.DecimalField( verbose_name="If YES, no. of units? ", decimal_places=3, max_digits=5, null=True, blank=True, ) patient_help = models.CharField( verbose_name=("Does the patient require help from" " anybody for everyday activities? "), max_length=10, choices=YES_NO_ND, help_text=("For example eating, drinking, washing," " brushing teeth, going to the toilet"), ) patient_problems = models.CharField( verbose_name= "Has the illness left the patient with any other problems?", max_length=10, choices=YES_NO_ND, ) rankin_score = models.CharField( verbose_name="Modified Rankin score", choices=RANKIN_SCORE, max_length=10, null=True, ) other_significant_dx = models.CharField( verbose_name="Other significant diagnosis since last visit?", max_length=5, choices=YES_NO_NA, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Follow-up" verbose_name_plural = "Follow-up"
class PatientHistory(CrfModelMixin): symptom = models.ManyToManyField( Symptom, blank=True, related_name="symptoms", verbose_name="What are your current symptoms?", ) headache_duration = models.IntegerField( verbose_name="If headache, how many days did it last?", validators=[MinValueValidator(1)], null=True, blank=True, ) visual_loss_duration = models.IntegerField( verbose_name="If visual loss, how many days did it last?", validators=[MinValueValidator(1)], null=True, blank=True, ) tb_history = models.CharField( verbose_name="Previous medical history of Tuberculosis?", max_length=5, choices=YES_NO, ) tb_site = models.CharField( verbose_name="If YES, site of TB?", max_length=15, choices=TB_SITE, default=NOT_APPLICABLE, ) tb_treatment = models.CharField( verbose_name="Are you currently taking TB treatment?", max_length=5, choices=YES_NO, ) taking_rifampicin = models.CharField( verbose_name="If YES, are you currently also taking Rifampicin?", max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, ) rifampicin_started_date = models.DateField( verbose_name="If YES, when did you first start taking Rifampicin?", validators=[date_not_future], null=True, blank=True, ) new_hiv_diagnosis = models.CharField( verbose_name="Is this a new HIV diagnosis?", max_length=5, choices=YES_NO ) taking_arv = models.CharField( verbose_name="If NO, has the patient ever been on ART?", max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, ) # retired first_arv_regimen = models.CharField( verbose_name="If YES, which drugs were prescribed for their first ART regimen?", max_length=50, choices=FIRST_ARV_REGIMEN_RETIRED, default=QUESTION_RETIRED, editable=False, ) # retired first_arv_regimen_other = OtherCharField(editable=False) # retired first_line_choice = models.CharField( verbose_name="If first line:", max_length=25, choices=FIRST_LINE_REGIMEN_RETIRED, default=QUESTION_RETIRED, editable=False, ) initial_arv_date = models.DateField( verbose_name=mark_safe( "If YES, when did the patient <u>start</u> ART for the first time." ), validators=[date_not_future], null=True, blank=True, ) initial_arv_date_estimated = IsDateEstimatedFieldNa( verbose_name="If YES, is this ART date estimated?", default=NOT_APPLICABLE ) initial_arv_regimen = models.ManyToManyField( ArvRegimens, verbose_name=mark_safe( "If YES, which drugs were prescribed for their first ART regimen?" ), related_name="initial_arv", ) initial_arv_regimen_other = OtherCharField() has_switched_regimen = models.CharField( verbose_name="Has the patient ever switched ART regimen?", max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, ) current_arv_date = models.DateField( verbose_name=mark_safe( "If YES, when was their <u>current or most recent</u> " "ART regimen started?" ), validators=[date_not_future], null=True, blank=True, ) current_arv_date_estimated = IsDateEstimatedFieldNa( verbose_name="If YES, is this ART date estimated?", default=NOT_APPLICABLE ) current_arv_regimen = models.ManyToManyField( ArvRegimens, verbose_name=mark_safe( "If YES, what is their current or most recent ART regimen?" ), related_name="current_arv", ) current_arv_regimen_other = OtherCharField() current_arv_is_defaulted = models.CharField( verbose_name=mark_safe( "Has the patient <u>now</u> defaulted from their ART regimen?" ), max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, help_text="'DEFAULTED' means no ART for at least one month.", ) current_arv_defaulted_date = models.DateField( verbose_name=mark_safe( "If the patient has DEFAULTED, on what date did they default " "from their <u>most recent</u> ART regimen?" ), validators=[date_not_future], null=True, blank=True, ) current_arv_defaulted_date_estimated = IsDateEstimatedFieldNa( verbose_name="If DEFAULTED, is this date estimated?", default=NOT_APPLICABLE ) current_arv_is_adherent = models.CharField( verbose_name=mark_safe( "If the patient is currently on ART, are they ADHERENT to " "their <u>current</u> ART regimen?" ), max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE, ) current_arv_tablets_missed = models.IntegerField( verbose_name=("If not ADHERENT, how many doses missed in the last month?"), validators=[MinValueValidator(0), MaxValueValidator(31)], null=True, blank=True, ) current_arv_decision = models.CharField( verbose_name=mark_safe( "What decision was made at admission regarding their " "<u>current</u> ART regimen?" ), max_length=25, choices=ARV_DECISION, default=NOT_APPLICABLE, ) # retired second_arv_regimen = models.CharField( verbose_name="Second line ARV regimen", max_length=50, choices=SECOND_ARV_REGIMEN_RETIRED, default=QUESTION_RETIRED, editable=False, ) # retired second_arv_regimen_other = OtherCharField(editable=False) # retired patient_adherence = models.CharField( verbose_name="Is the patient reportedly adherent?", max_length=25, choices=YES_NO_NA_RETIRED, default=QUESTION_RETIRED, editable=False, ) # retired last_dose = models.IntegerField( verbose_name=( "If no tablets taken this month, how many months " "since the last dose taken?" ), validators=[MinValueValidator(0)], null=True, blank=True, editable=False, ) last_viral_load = models.DecimalField( verbose_name="Last Viral Load, if known?", decimal_places=3, max_digits=10, null=True, blank=True, help_text="copies/mL", ) viral_load_date = models.DateField( verbose_name="Viral Load date", validators=[date_not_future], null=True, blank=True, ) vl_date_estimated = IsDateEstimatedFieldNa( verbose_name=("Is the subject's Viral Load date estimated?"), default=NOT_APPLICABLE, ) last_cd4 = models.IntegerField( verbose_name="Last CD4, if known?", validators=[MinValueValidator(1), MaxValueValidator(2500)], null=True, blank=True, help_text=mark_safe("acceptable units are mm<sup>3</sup>"), ) cd4_date = models.DateField( verbose_name="CD4 date", validators=[date_not_future], null=True, blank=True ) cd4_date_estimated = IsDateEstimatedFieldNa( verbose_name=("Is the subject's CD4 date estimated?"), default=NOT_APPLICABLE ) temp = models.DecimalField( verbose_name="Temperature:", validators=[MinValueValidator(30), MaxValueValidator(45)], decimal_places=1, max_digits=3, help_text="in degrees Celcius", ) heart_rate = models.IntegerField( verbose_name="Heart rate:", validators=[MinValueValidator(30), MaxValueValidator(200)], help_text="bpm", ) sys_blood_pressure = models.IntegerField( verbose_name="Blood pressure: systolic", validators=[MinValueValidator(50), MaxValueValidator(220)], help_text="in mm. format SYS, e.g. 120", ) dia_blood_pressure = models.IntegerField( verbose_name="Blood pressure: diastolic", validators=[MinValueValidator(20), MaxValueValidator(150)], help_text="in Hg. format DIA, e.g. 80", ) respiratory_rate = models.IntegerField( verbose_name="Respiratory rate:", validators=[MinValueValidator(6), MaxValueValidator(50)], help_text="breaths/min", ) weight = models.DecimalField( verbose_name="Weight:", validators=[MinValueValidator(20), MaxValueValidator(150)], decimal_places=1, max_digits=4, help_text="kg", ) weight_determination = models.CharField( verbose_name="Is weight estimated or measured?", max_length=15, choices=WEIGHT_DETERMINATION, ) glasgow_coma_score = models.IntegerField( verbose_name="Glasgow Coma Score:", validators=[MinValueValidator(3), MaxValueValidator(15)], help_text="/15", ) neurological = models.ManyToManyField(Neurological, blank=True) neurological_other = OtherCharField( verbose_name='If "Other CN palsy", specify', max_length=250, blank=True, null=True, ) focal_neurologic_deficit = models.TextField( verbose_name='If "Focal neurologic deficit" chosen, please specify details:', null=True, blank=True, ) visual_acuity_day = models.DateField( verbose_name="Study day visual acuity recorded?", validators=[date_not_future], null=True, blank=True, ) left_acuity = models.DecimalField( verbose_name="Visual acuity left eye:", decimal_places=3, max_digits=4, null=True, blank=True, ) right_acuity = models.DecimalField( verbose_name="Visual acuity right eye", decimal_places=3, max_digits=4, null=True, blank=True, ) ecog_score = models.CharField( verbose_name="ECOG Disability Score", max_length=15, choices=ECOG_SCORE ) ecog_score_value = models.CharField( verbose_name="ECOG Score", max_length=15, choices=ECOG_SCORE ) lung_exam = models.CharField( verbose_name="Abnormal lung exam:", max_length=5, choices=YES_NO ) cryptococcal_lesions = models.CharField( verbose_name="Cryptococcal related skin lesions:", max_length=5, choices=YES_NO ) specify_medications = models.ManyToManyField(Medication, blank=True) specify_medications_other = models.TextField(max_length=150, blank=True, null=True) previous_oi = models.CharField( verbose_name="Previous opportunistic infection other than TB?", max_length=5, choices=YES_NO, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Patient's History" verbose_name_plural = "Patient's History"
class Radiology(CrfModelMixin): cxr_done = models.CharField(verbose_name="Is CXR done", choices=YES_NO, max_length=5) cxr_date = models.DateField( verbose_name="If yes, when was CXR done", validators=[date_not_future], blank=True, null=True, ) cxr_type = models.ManyToManyField(CXRType, verbose_name="If YES, result", blank=True) infiltrate_location = models.ManyToManyField( InfiltrateLocation, verbose_name="If infiltrates, specify location", blank=True) cxr_description = models.TextField(verbose_name="Description/Comments", blank=True, null=True) ct_performed = models.CharField( verbose_name="CT/MRI brain scan performed?", choices=YES_NO, max_length=5) ct_performed_date = models.DateTimeField( verbose_name="Date CT performed", validators=[datetime_not_future], editable=True, blank=True, null=True, ) scanned_with_contrast = models.CharField( verbose_name="CT/MRI brain scan performed with contrast?", blank=False, choices=YES_NO_NA, default=NOT_APPLICABLE, max_length=5, null=False, ) brain_imaging_reason = models.CharField( verbose_name="Reason for brain imaging", blank=False, choices=BRAIN_IMAGINING_REASON, default=NOT_APPLICABLE, max_length=25, null=True, ) brain_imaging_reason_other = models.CharField( verbose_name="If other, please specify", blank=True, max_length=50, null=True) are_results_abnormal = models.CharField(blank=False, choices=YES_NO_NA, default=NOT_APPLICABLE, null=False, max_length=5) abnormal_results_reason = models.ManyToManyField( AbnormalResultsReason, verbose_name="If results are abnormal, what is the reason?", blank=True, ) abnormal_results_reason_other = models.CharField( verbose_name="If other, please specify reason", blank=True, max_length=50, null=True, ) infarcts_location = models.CharField( verbose_name= "If results are abnormal because of Infarcts, what is the location?", blank=True, max_length=50, null=True, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Radiology" verbose_name_plural = "Radiology"
class PkPdCrf(CrfModelMixin): albumin = models.IntegerField(verbose_name='Albumin', null=True, blank=True, help_text='Units in g/L') ambisome_dose = models.IntegerField(verbose_name='Ambisome dose given', null=True, blank=True, help_text='Units in mg') ambisome_started_datetime = models.DateTimeField( verbose_name='Date and time Ambisome infusion started?', null=True, blank=True) ambisome_ended_datetime = models.DateTimeField( verbose_name='Date and time Ambisome infusion stopped', null=True, blank=True) full_ambisome_dose_given = models.CharField( verbose_name='Was the entire Ambisome dose given?', choices=YES_NO, max_length=5, null=True, blank=True) flucytosine_dose = models.IntegerField(verbose_name='Flucytosine dose?', null=True, blank=True, help_text='Units in mg') flucytosine_dose_one_given = models.CharField( verbose_name='Flucytosine <u>DOSE 1</u> given? ', choices=YES_NO, max_length=5, null=True, blank=True) flucytosine_dose_one_datetime = models.DateTimeField( verbose_name=mark_safe( 'Date and time Flucytosine <u>DOSE 1</u> was swallowed?'), null=True, blank=True) flucytosine_dose_two_given = models.CharField( verbose_name='Flucytosine <u>DOSE 2</u> given? ', choices=YES_NO, max_length=5, null=True, blank=True) flucytosine_dose_two_datetime = models.DateTimeField( verbose_name=mark_safe( 'Date and time Flucytosine <u>DOSE 2</u> was swallowed?'), null=True, blank=True) flucytosine_dose_three_given = models.CharField( verbose_name='Flucytosine <u>DOSE 3</u> given? ', choices=YES_NO, max_length=5, null=True, blank=True) flucytosine_dose_three_datetime = models.DateTimeField( verbose_name=mark_safe( 'Date and time Flucytosine <u>DOSE 3</u> was swallowed?'), null=True, blank=True) flucytosine_dose_four_given = models.CharField( verbose_name='Flucytosine <u>DOSE 4</u> given? ', choices=YES_NO, max_length=5, null=True, blank=True) flucytosine_dose_four_datetime = models.DateTimeField( verbose_name=mark_safe( 'Date and time Flucytosine <u>DOSE 4</u> was swallowed?'), null=True, blank=True) flucytosine_dose_reason_missed = models.TextField( verbose_name='If any Flucytosine doses not given, provide reason', max_length=75, null=True, blank=True) fluconazole_dose = models.IntegerField(verbose_name='Fluconazole dose?', null=True, blank=True, help_text='Units in mg') fluconazole_dose_given = models.CharField( verbose_name='Was the Fluconazole dose given?', choices=YES_NO, max_length=5, null=True, blank=True) fluconazole_dose_datetime = models.DateTimeField( verbose_name='Date and time Fluconazole was swallowed?', null=True, blank=True) fluconazole_dose_reason_missed = models.TextField( verbose_name='If Fluconazole dose not given, provide reason', max_length=75, null=True, blank=True) blood_sample_one_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 1</u> taken?'), null=True, blank=True) blood_sample_two_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 2</u> taken?'), null=True, blank=True) blood_sample_three_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 3</u> taken?'), null=True, blank=True) blood_sample_four_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 4</u> taken?'), null=True, blank=True) blood_sample_five_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 5</u> taken?'), null=True, blank=True) blood_sample_six_datetime = models.DateTimeField(verbose_name=mark_safe( 'Date and time blood <u>SAMPLE 6</u> taken?'), null=True, blank=True) blood_sample_missed = models.CharField( verbose_name='Were any blood samples missed?', choices=YES_NO, max_length=5, null=True, blank=True) blood_sample_reason_missed = models.TextField( verbose_name='If any blood samples missed, provide reason', max_length=75, null=True, blank=True) pre_dose_lp = models.CharField(verbose_name='Is this a pre-dose LP?', choices=YES_NO, max_length=5, null=True, blank=True) post_dose_lp = models.CharField(verbose_name='Is this a post-dose LP?', choices=YES_NO, max_length=5, null=True, blank=True) time_csf_sample_taken = models.DateTimeField( verbose_name='What date and time was the CSF sample taken?', null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'PK/PD' verbose_name_plural = 'PK/PD'
class MedicalExpenses(CrfModelMixin): info_source = models.CharField( verbose_name="What is the main source of this information?", max_length=25, choices=PATIENT_REL, ) currency = models.CharField(verbose_name="Which currency do you use?", max_length=20, choices=CURRENCY) food_spend = models.DecimalField( verbose_name="How much do you/your family spend on food in a week?", decimal_places=2, max_digits=15, null=True, validators=[MinValueValidator(0)], ) utilities_spend = models.DecimalField( verbose_name= "How much do you/your family spent on rent and utilities a month?", decimal_places=2, max_digits=15, null=True, validators=[MinValueValidator(0)], ) item_spend = models.DecimalField( verbose_name= ("How much have you spent on large items (e.g. furniture, electrical " "items, cars) in the last year?"), decimal_places=2, max_digits=15, null=True, validators=[MinValueValidator(0)], ) subject_spent_last_4wks = models.DecimalField( verbose_name=("Over the last 4/10 weeks, how much have you " "spent on activities relating to your health?"), decimal_places=2, max_digits=15, null=True, validators=[MinValueValidator(0)], help_text=( "On D1 record data for the four weeks prior to recruitment. " "On W10 record data for the ten weeks since recruitment."), ) someone_spent_last_4wks = models.DecimalField( verbose_name=("Over the last 4/10 weeks, how much has someone else " "spent on activities relating to your health?"), decimal_places=2, max_digits=15, null=True, validators=[MinValueValidator(0)], help_text=( "On D1 record data for the four weeks prior to recruitment. " "On W10 record data for the ten weeks since recruitment."), ) total_spent_last_4wks = models.DecimalField( verbose_name= ("How much in total has been spent on your healthcare in the last 4/10 weeks?" ), decimal_places=2, max_digits=16, null=True, validators=[MinValueValidator(0)], help_text=( "On D1 record data for the four weeks prior to recruitment. " "On W10 record data for the ten weeks since recruitment."), ) care_before_hospital = models.CharField( verbose_name=( "Have you received any treatment or care " "for your present condition, before coming to the hospital?"), max_length=5, choices=YES_NO, help_text="If YES, please complete medical expenses part 2", ) duration_present_condition = models.IntegerField( verbose_name="How long have you been sick with your current condition?", validators=[MinValueValidator(0)], null=True, help_text="in days", ) activities_missed = models.CharField( verbose_name=("What would you have been doing if you were not sick " "with your present condition"), max_length=25, null=True, choices=ACTIVITIES_MISSED, ) activities_missed_other = OtherCharField(max_length=25, blank=True, null=True) time_off_work = models.DecimalField( verbose_name="How much time did you take off work?", max_digits=4, decimal_places=1, validators=[MinValueValidator(0)], blank=True, null=True, help_text="in days", ) carer_time_off = models.IntegerField( verbose_name=("How much time did a caring family member " "take to accompany you to the hospital?"), validators=[MinValueValidator(0)], blank=True, null=True, help_text="in days", ) loss_of_earnings = models.CharField( verbose_name="Did you lose earnings as a result?", max_length=5, choices=YES_NO_NA, ) earnings_lost_amount = models.DecimalField( verbose_name="How much did you lose?", decimal_places=2, max_digits=15, validators=[MinValueValidator(0)], null=True, blank=True, ) form_of_transport = models.CharField( verbose_name="Which form of transport did you take to get here today?", max_length=25, default=NOT_APPLICABLE, choices=TRANSPORT, ) transport_fare = models.DecimalField( verbose_name="How much did you spend on the transport (in total)?", decimal_places=2, max_digits=15, validators=[MinValueValidator(0)], blank=True, null=True, ) travel_time = models.CharField( verbose_name="How long did it take you to reach there?", validators=[hm_validator], max_length=8, help_text="Specify as hours:minutes (format HH:MM)", null=True, blank=True, ) loans = models.CharField( verbose_name="Did you take out any loans to pay for your healthcare?", max_length=5, choices=YES_NO, ) sold_anything = models.CharField( verbose_name="Did you sell anything to pay for your healthcare?", max_length=5, choices=YES_NO, ) private_healthcare = models.CharField( verbose_name="Do you have private healthcare insurance?", max_length=5, choices=YES_NO, ) healthcare_insurance = models.CharField( verbose_name="Did you use it to help pay for your healthcare?", max_length=5, choices=YES_NO_NA, ) welfare = models.CharField( verbose_name="Do you receive any welfare or social service support?", max_length=5, choices=YES_NO, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Health Economics: Medical Expenses" verbose_name_plural = "Health Economics: Medical Expenses"
class Week2(ClinicalAssessmentModelMixin, CrfModelMixin): discharged = models.CharField(verbose_name='Discharged?', max_length=25, choices=YES_NO) discharge_date = models.DateField(validators=[date_not_future], null=True, blank=True) died = models.CharField(verbose_name='Died?', max_length=25, choices=YES_NO) death_date_time = models.DateTimeField(validators=[datetime_not_future], null=True, blank=True) ampho_start_date = models.DateField( verbose_name='Amphotericin B start date: ', validators=[date_not_future], null=True, blank=True) ampho_end_date = models.DateField(verbose_name='Amphotericin B end date: ', validators=[date_not_future], null=True, blank=True) ampho_duration = models.IntegerField( verbose_name='Amphotericin B treatment duration', null=True, blank=True) flucon_start_date = models.DateField( verbose_name='Fluconazole start date:', validators=[date_not_future], null=True, blank=True) flucon_stop_date = models.DateField(verbose_name='Fluconazole end date:', validators=[date_not_future], null=True, blank=True) flucon_duration = models.IntegerField( verbose_name='Fluconazole treatment duration:', null=True, blank=True) flucy_start_date = models.DateField(verbose_name='Flucytosine start date:', validators=[date_not_future], null=True, blank=True) flucy_stop_date = models.DateField(verbose_name='Flucytosine end date:', validators=[date_not_future], null=True, blank=True) flucy_duration = models.IntegerField( verbose_name='Flucytosine treatment duration:', null=True, blank=True) ambi_start_date = models.DateField(verbose_name='Ambisome start date:', validators=[date_not_future], null=True, blank=True) ambi_stop_date = models.DateField(verbose_name='Ambisome end date:', validators=[date_not_future], null=True, blank=True) ambi_duration = models.IntegerField( verbose_name='Ambisome treatment duration:', null=True, blank=True) drug_intervention = models.ManyToManyField( OtherDrug, verbose_name="Other drugs/interventions given during first 14 days", ) drug_intervention_other = models.CharField( verbose_name='If other, please specify:', blank=True, max_length=50, null=True) antibiotic = models.ManyToManyField( Antibiotic, blank=True, verbose_name="Were any of the following antibiotics given?", ) antibiotic_other = models.CharField( verbose_name='If other antibiotics, please specify:', max_length=50, null=True, blank=True) blood_received = models.CharField( verbose_name='Blood transfusion received?', max_length=25, choices=YES_NO) units = models.IntegerField(verbose_name='If YES, no. of units', validators=[MinValueValidator(1)], null=True, blank=True) temperature = models.FloatField(verbose_name='Temperature', null=True, blank=True, default=None) weight = models.DecimalField( verbose_name='Weight:', validators=[MinValueValidator(20), MaxValueValidator(150)], decimal_places=1, max_digits=4, help_text='kg') medicines = models.ManyToManyField(Day14Medication, verbose_name='Medicine day 14:') medicine_other = models.CharField(verbose_name='If other, please specify:', max_length=50, null=True, blank=True) significant_dx = models.CharField( verbose_name='Other significant diagnoses since enrolment?', max_length=25, choices=YES_NO) significant_dx_datetime = models.DateTimeField( validators=[date_not_future], null=True, blank=True) flucon_missed_doses = models.CharField( verbose_name='Were any Fluconazole drug doses missed?', max_length=25, choices=YES_NO) amphotericin_missed_doses = models.CharField( verbose_name='Were any Amphotericin B drug doses missed?', max_length=25, choices=YES_NO) other_significant_dx = models.CharField( verbose_name='Other significant diagnosis since enrollment?', max_length=5, choices=YES_NO) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Week 2' verbose_name_plural = 'Week 2'
class LumbarPunctureCsf(CrfModelMixin, BiosynexSemiQuantitativeCragMixin): lp_datetime = models.DateTimeField(verbose_name='LP Date and Time', validators=[datetime_not_future]) qc_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='qcrequisition', verbose_name='QC Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) qc_assay_datetime = models.DateTimeField( verbose_name='QC Result Report Date and Time', validators=[datetime_not_future], blank=True, null=True) csf_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='csfrequisition', verbose_name='CSF Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) csf_assay_datetime = models.DateTimeField( verbose_name='CSF Result Report Date and Time', validators=[datetime_not_future], null=True, blank=True) reason_for_lp = models.CharField(verbose_name='Reason for LP', max_length=50, choices=LP_REASON) opening_pressure = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(99)], help_text=mark_safe('Units cm of H<sub>2</sub>O')) closing_pressure = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(99)], help_text=mark_safe('Units cm of H<sub>2</sub>O')) csf_amount_removed = models.IntegerField( blank=True, null=True, verbose_name='CSF amount removed ', validators=[MinValueValidator(1)], help_text='Units ml') quantitative_culture = models.IntegerField( blank=True, null=True, validators=[MinValueValidator(0), MaxValueValidator(9999999)], help_text='Units CFU/ml') csf_culture = models.CharField( verbose_name='Other organism (non-Cryptococcus)', max_length=18, choices=YES_NO_NOT_DONE_WAIT_RESULTS, default=AWAITING_RESULTS, help_text='Complete after getting the results.') other_csf_culture = models.CharField( verbose_name='If YES, specify organism:', max_length=75, blank=True, null=True) csf_wbc_cell_count = models.IntegerField( verbose_name='Total CSF WBC cell count:', help_text=mark_safe('acceptable units are mm<sup>3</sup>'), validators=[MinValueValidator(0), MaxValueValidator(999)], null=True, blank=True) differential_lymphocyte_count = models.IntegerField( verbose_name='Differential lymphocyte cell count:', validators=[MinValueValidator(0), MaxValueValidator(999)], blank=True, null=True, help_text=mark_safe('acceptable units are mm<sup>3</sup> or %')) differential_lymphocyte_unit = models.CharField(choices=MM3_PERC_UNITS, max_length=6, null=True, blank=True) differential_neutrophil_count = models.IntegerField( verbose_name='Differential neutrophil cell count:', validators=[MinValueValidator(0), MaxValueValidator(999)], blank=True, null=True, help_text=mark_safe('acceptable units are mm<sup>3</sup> or %')) differential_neutrophil_unit = models.CharField(choices=MM3_PERC_UNITS, max_length=6, null=True, blank=True) india_ink = models.CharField( max_length=15, choices=POS_NEG, null=True, ) csf_glucose = models.DecimalField(verbose_name='CSF glucose:', decimal_places=1, max_digits=3, blank=True, null=True, help_text='Units in mmol/L or mg/dL') csf_glucose_units = models.CharField( verbose_name='CSF glucose units:', max_length=6, choices=MG_MMOL_UNITS, blank=True, null=True, ) csf_protein = models.DecimalField(verbose_name='CSF protein:', decimal_places=2, max_digits=4, blank=True, null=True, help_text='Units in g/dL') csf_cr_ag = models.CharField(verbose_name='CSF CrAg:', max_length=15, choices=POS_NEG, null=True) csf_cr_ag_lfa = models.CharField( verbose_name='CSF CrAg done by CSF CrAg LFA:', max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Lumbar Puncture/Cerebrospinal Fluid' verbose_name_plural = 'Lumbar Puncture/Cerebrospinal Fluid'
class BloodResult(CrfModelMixin, ActionItemModelMixin, TrackingIdentifierModelMixin, BiosynexSemiQuantitativeCragMixin): action_cls = BloodResultAction tracking_identifier_prefix = 'BR' ft_fields = [ 'creatinine', 'urea', 'sodium', 'potassium', 'magnesium', 'alt' ] cbc_fields = ['haemoglobin', 'wbc', 'neutrophil', 'platelets'] ft_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='ft', verbose_name='Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) ft_assay_datetime = models.DateTimeField( verbose_name='Result Report Date and Time', validators=[datetime_not_future], null=True, blank=True) cbc_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='cbc', verbose_name='Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) cbc_assay_datetime = models.DateTimeField( verbose_name='Result Report Date and Time', validators=[datetime_not_future], null=True, blank=True) cd4_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='cd4', verbose_name='Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) cd4_assay_datetime = models.DateTimeField( verbose_name='Result Report Date and Time', validators=[datetime_not_future], null=True, blank=True) vl_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name='vl', verbose_name='Requisition', null=True, blank=True, help_text= 'Start typing the requisition identifier or select one from this visit' ) vl_assay_datetime = models.DateTimeField( verbose_name='Result Report Date and Time', validators=[datetime_not_future], null=True, blank=True) wbc = models.DecimalField(verbose_name='WBC', decimal_places=1, max_digits=6, null=True, blank=True) wbc_units = models.CharField(verbose_name='units', max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True) wbc_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) wbc_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) platelets = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(9999)], null=True, blank=True) platelets_units = models.CharField(verbose_name='units', max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True) platelets_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) platelets_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) haemoglobin = models.DecimalField(decimal_places=1, max_digits=6, null=True, blank=True) haemoglobin_units = models.CharField(verbose_name='units', max_length=10, choices=((GRAMS_PER_DECILITER, GRAMS_PER_DECILITER), ), null=True, blank=True) haemoglobin_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) haemoglobin_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) neutrophil = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) neutrophil_units = models.CharField(verbose_name='units', max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True) neutrophil_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) neutrophil_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) creatinine = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) creatinine_units = models.CharField(verbose_name='units', choices=MG_UMOL_UNITS, max_length=25, null=True, blank=True) creatinine_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) creatinine_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) sodium = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(999)], null=True, blank=True) sodium_units = models.CharField(verbose_name='units', max_length=10, choices=((MILLIMOLES_PER_LITER, MILLIMOLES_PER_LITER), ), null=True, blank=True) sodium_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) sodium_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) potassium = models.DecimalField(decimal_places=1, max_digits=2, null=True, blank=True) potassium_units = models.CharField(verbose_name='units', max_length=10, choices=((MILLIMOLES_PER_LITER, MILLIMOLES_PER_LITER), ), null=True, blank=True) potassium_abnormal = models.CharField( verbose_name='abnormal', choices=YES_NO, # default=NO, max_length=25, null=True, blank=True) potassium_reportable = models.CharField( verbose_name='reportable', choices=REPORTABLE, # default=NOT_APPLICABLE, max_length=25, null=True, blank=True) magnesium = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) magnesium_units = models.CharField(verbose_name='units', choices=MG_MMOL_UNITS, null=True, blank=True, max_length=25) magnesium_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, null=True, blank=True, max_length=25) magnesium_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, null=True, blank=True, max_length=25) alt = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(2999)], verbose_name='ALT', null=True, blank=True) alt_units = models.CharField(verbose_name='units', max_length=10, choices=((IU_LITER, IU_LITER), ), null=True, blank=True) alt_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) alt_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) urea = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) urea_units = models.CharField(verbose_name='units', choices=MG_MMOL_UNITS, max_length=25, null=True, blank=True) urea_abnormal = models.CharField( verbose_name='abnormal', choices=YES_NO, # default=NO, max_length=25, null=True, blank=True) urea_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) cd4 = models.IntegerField( verbose_name='abs CD4', validators=[MinValueValidator(1), MaxValueValidator(999)], blank=True, null=True) cd4_units = models.CharField(verbose_name='units', max_length=10, choices=((CELLS_PER_MILLIMETER_CUBED, CELLS_PER_MILLIMETER_CUBED), ), null=True, blank=True) cd4_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) cd4_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) vl = models.FloatField(verbose_name='Viral Load', validators=[MinValueValidator(0.0)], blank=True, null=True) vl_units = models.CharField(verbose_name='units', max_length=10, choices=((COPIES_PER_MILLILITER, COPIES_PER_MILLILITER), ), null=True, blank=True) vl_abnormal = models.CharField(verbose_name='abnormal', choices=YES_NO, max_length=25, null=True, blank=True) vl_reportable = models.CharField(verbose_name='reportable', choices=REPORTABLE, max_length=25, null=True, blank=True) results_abnormal = models.CharField( verbose_name='Are any of the above results abnormal?', choices=YES_NO, max_length=25) results_reportable = models.CharField( verbose_name='If any results are abnormal, are results within grade III ' 'or above?', max_length=25, choices=YES_NO_NA, help_text= ('If YES, this value will open Adverse Event Form.<br/><br/>' 'Note: On Day 1 only abnormal bloods should not be reported as adverse' 'events.')) summary = models.TextField(null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() def save(self, *args, **kwargs): self.summary = '\n'.join(self.get_summary()) super().save(*args, **kwargs) def get_summary(self): registered_subject = RegisteredSubject.objects.get( subject_identifier=self.subject_visit.subject_identifier) opts = dict(gender=registered_subject.gender, dob=registered_subject.dob, report_datetime=self.subject_visit.report_datetime) summary = [] for field in [f.name for f in self._meta.fields]: value = getattr(self, field) grp = site_reportables.get('ambition').get(field) if value and grp: units = getattr(self, f'{field}_units') opts.update(units=units) grade = grp.get_grade(value, **opts) if grade and grade.grade: summary.append(f'{field}: {grade.description}.') elif not grade: normal = grp.get_normal(value, **opts) if not normal: summary.append(f'{field}: {value} {units} is abnormal') return summary @property def action_item_reason(self): return self.summary @property def abnormal(self): return self.results_abnormal @property def reportable(self): return self.results_reportable class Meta(CrfModelMixin.Meta): verbose_name = 'Blood Result' verbose_name_plural = 'Blood Results'
class PatientHistory(CrfModelMixin): symptom = models.ManyToManyField( Symptom, blank=True, related_name='symptoms', verbose_name='What are your current symptoms?') headache_duration = models.IntegerField( verbose_name='If headache, how many days did it last?', validators=[MinValueValidator(1)], null=True, blank=True) visual_loss_duration = models.IntegerField( verbose_name='If visual loss, how many days did it last?', validators=[MinValueValidator(1)], null=True, blank=True) tb_history = models.CharField( verbose_name='Previous medical history of Tuberculosis?', max_length=5, choices=YES_NO) tb_site = models.CharField(verbose_name='If YES, site of TB?', max_length=15, choices=TB_SITE, default=NOT_APPLICABLE) tb_treatment = models.CharField( verbose_name='Are you currently taking TB treatment?', max_length=5, choices=YES_NO) taking_rifampicin = models.CharField( verbose_name='If YES, are you currently also taking Rifampicin?', max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE) rifampicin_started_date = models.DateField( verbose_name='If YES, when did you first start taking Rifampicin?', validators=[date_not_future], null=True, blank=True) new_hiv_diagnosis = models.CharField( verbose_name='Is this a new HIV diagnosis?', max_length=5, choices=YES_NO) taking_arv = models.CharField(verbose_name='If NO, already taking ARVs?', max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE) arv_date = models.DateField(verbose_name='If YES, date ARVs were started.', validators=[date_not_future], null=True, blank=True) arv_date_estimated = IsDateEstimatedFieldNa( verbose_name=("Is the subject's ARV date estimated?"), default=NOT_APPLICABLE) first_arv_regimen = models.CharField( verbose_name='Drug used in first line ARV regimen', max_length=50, choices=FIRST_ARV_REGIMEN, default=NOT_APPLICABLE) first_arv_regimen_other = OtherCharField() second_arv_regimen = models.CharField( verbose_name='Second line ARV regimen', max_length=50, choices=SECOND_ARV_REGIMEN, default=NOT_APPLICABLE) second_arv_regimen_other = OtherCharField() first_line_choice = models.CharField(verbose_name='If first line:', max_length=5, choices=FIRST_LINE_REGIMEN, default=NOT_APPLICABLE) patient_adherence = models.CharField( verbose_name='Is the patient reportedly adherent?', max_length=5, choices=YES_NO_NA, default=NOT_APPLICABLE) tablets_missed = models.IntegerField( verbose_name=('If not adherent, how many tablets missed in ' 'the last month?'), validators=[MinValueValidator(0), MaxValueValidator(31)], null=True, blank=True) last_dose = models.IntegerField( verbose_name=('If no tablets taken this month, how many months ' 'since the last dose taken?'), validators=[MinValueValidator(0)], null=True, blank=True) last_viral_load = models.DecimalField( verbose_name='Last Viral Load, if known?', decimal_places=3, max_digits=10, null=True, blank=True, help_text='copies/mL') viral_load_date = models.DateField(verbose_name='Viral Load date', validators=[date_not_future], null=True, blank=True) vl_date_estimated = IsDateEstimatedFieldNa( verbose_name=("Is the subject's Viral Load date estimated?"), default=NOT_APPLICABLE) last_cd4 = models.IntegerField( verbose_name='Last CD4, if known?', validators=[MinValueValidator(1), MaxValueValidator(2500)], null=True, blank=True, help_text=mark_safe('acceptable units are mm<sup>3</sup>')) cd4_date = models.DateField(verbose_name='CD4 date', validators=[date_not_future], null=True, blank=True) cd4_date_estimated = IsDateEstimatedFieldNa( verbose_name=("Is the subject's CD4 date estimated?"), default=NOT_APPLICABLE) temp = models.DecimalField( verbose_name='Temperature:', validators=[MinValueValidator(30), MaxValueValidator(45)], decimal_places=1, max_digits=3, help_text='in degrees Celcius') heart_rate = models.IntegerField( verbose_name='Heart rate:', validators=[MinValueValidator(30), MaxValueValidator(200)], help_text='bpm') sys_blood_pressure = models.IntegerField( verbose_name='Blood pressure: systolic', validators=[MinValueValidator(50), MaxValueValidator(220)], help_text='in mm. format SYS, e.g. 120') dia_blood_pressure = models.IntegerField( verbose_name='Blood pressure: diastolic', validators=[MinValueValidator(20), MaxValueValidator(150)], help_text='in Hg. format DIA, e.g. 80') respiratory_rate = models.IntegerField( verbose_name='Respiratory rate:', validators=[MinValueValidator(6), MaxValueValidator(50)], help_text='breaths/min') weight = models.DecimalField( verbose_name='Weight:', validators=[MinValueValidator(20), MaxValueValidator(150)], decimal_places=1, max_digits=4, help_text='kg') weight_determination = models.CharField( verbose_name='Is weight estimated or measured?', max_length=15, choices=WEIGHT_DETERMINATION) glasgow_coma_score = models.IntegerField( verbose_name='Glasgow Coma Score:', validators=[MinValueValidator(3), MaxValueValidator(15)], help_text='/15') neurological = models.ManyToManyField(Neurological, blank=True) neurological_other = OtherCharField( verbose_name='If "Other CN palsy", specify', max_length=250, blank=True, null=True) focal_neurologic_deficit = models.TextField( verbose_name= 'If "Focal neurologic deficit" chosen, please specify details:', null=True, blank=True) visual_acuity_day = models.DateField( verbose_name='Study day visual acuity recorded?', validators=[date_not_future], null=True, blank=True) left_acuity = models.DecimalField(verbose_name='Visual acuity left eye:', decimal_places=3, max_digits=4, null=True, blank=True) right_acuity = models.DecimalField(verbose_name='Visual acuity right eye', decimal_places=3, max_digits=4, null=True, blank=True) ecog_score = models.CharField(verbose_name='ECOG Disability Score', max_length=15, choices=ECOG_SCORE) ecog_score_value = models.CharField(verbose_name='ECOG Score', max_length=15, choices=ECOG_SCORE) lung_exam = models.CharField(verbose_name='Abnormal lung exam:', max_length=5, choices=YES_NO) cryptococcal_lesions = models.CharField( verbose_name='Cryptococcal related skin lesions:', max_length=5, choices=YES_NO) specify_medications = models.ManyToManyField(Medication, blank=True) specify_medications_other = models.TextField(max_length=150, blank=True, null=True) previous_oi = models.CharField( verbose_name='Previous opportunistic infection other than TB?', max_length=5, choices=YES_NO) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = 'Patient\'s History' verbose_name_plural = 'Patient\'s History'
class Week2( ClinicalAssessmentModelMixin, StudyMedicationModelMixin, MedAndDrugInterventionModelMixin, BloodTransfusionModelMixin, CrfModelMixin, ): discharged = models.CharField( verbose_name="Discharged", max_length=25, choices=YES_NO ) discharge_date = models.DateField( validators=[date_not_future], null=True, blank=True ) research_discharge_date = models.DateField( verbose_name="On which date did the research team feel the patient was well " "enough to go home", validators=[date_not_future], null=True, blank=True, ) died = models.CharField(verbose_name="Died", max_length=25, choices=YES_NO) death_date_time = models.DateTimeField( validators=[datetime_not_future], null=True, blank=True ) temperature = models.FloatField( verbose_name="Temperature", null=True, blank=True, default=None ) weight = models.DecimalField( verbose_name="Weight", validators=[MinValueValidator(20), MaxValueValidator(150)], decimal_places=1, max_digits=4, help_text="kg", ) significant_dx = models.CharField( verbose_name="Other significant diagnoses since enrolment", max_length=25, choices=YES_NO, ) significant_dx_datetime = models.DateTimeField( validators=[date_not_future], null=True, blank=True ) flucon_missed_doses = models.CharField( verbose_name="Were any Fluconazole drug doses missed", max_length=25, choices=YES_NO, ) amphotericin_missed_doses = models.CharField( verbose_name="Were any Amphotericin B drug doses missed", max_length=25, choices=YES_NO, ) other_significant_dx = models.CharField( verbose_name="Other significant diagnosis since enrollment", max_length=5, choices=YES_NO, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Week 2" verbose_name_plural = "Week 2"
class BloodResult( CrfModelMixin, ActionModelMixin, TrackingModelMixin, BiosynexSemiQuantitativeCragMixin, ): action_name = BLOOD_RESULTS_ACTION tracking_identifier_prefix = "BR" ft_fields = [ "creatinine", "urea", "sodium", "potassium", "magnesium", "alt" ] cbc_fields = ["haemoglobin", "wbc", "neutrophil", "platelets"] ft_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="ft", verbose_name="Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) ft_assay_datetime = models.DateTimeField( verbose_name="Result Report Date and Time", validators=[datetime_not_future], null=True, blank=True, ) cbc_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="cbc", verbose_name="Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) cbc_assay_datetime = models.DateTimeField( verbose_name="Result Report Date and Time", validators=[datetime_not_future], null=True, blank=True, ) cd4_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="cd4", verbose_name="Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) cd4_assay_datetime = models.DateTimeField( verbose_name="Result Report Date and Time", validators=[datetime_not_future], null=True, blank=True, ) vl_requisition = models.ForeignKey( SubjectRequisition, on_delete=PROTECT, related_name="vl", verbose_name="Requisition", null=True, blank=True, help_text= "Start typing the requisition identifier or select one from this visit", ) vl_assay_datetime = models.DateTimeField( verbose_name="Result Report Date and Time", validators=[datetime_not_future], null=True, blank=True, ) wbc = models.DecimalField(verbose_name="WBC", decimal_places=2, max_digits=6, null=True, blank=True) wbc_units = models.CharField( verbose_name="units", max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True, ) wbc_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) wbc_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) platelets = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(9999)], null=True, blank=True, ) platelets_units = models.CharField( verbose_name="units", max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True, ) platelets_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) platelets_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) haemoglobin = models.DecimalField(decimal_places=1, max_digits=6, null=True, blank=True) haemoglobin_units = models.CharField( verbose_name="units", max_length=10, choices=((GRAMS_PER_DECILITER, GRAMS_PER_DECILITER), ), null=True, blank=True, ) haemoglobin_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) haemoglobin_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) neutrophil = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) neutrophil_units = models.CharField( verbose_name="units", max_length=10, choices=((TEN_X_9_PER_LITER, TEN_X_9_PER_LITER), ), null=True, blank=True, ) neutrophil_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) neutrophil_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) creatinine = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) creatinine_units = models.CharField( verbose_name="units", choices=MG_UMOL_UNITS, max_length=25, null=True, blank=True, ) creatinine_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) creatinine_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) sodium = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(999)], null=True, blank=True) sodium_units = models.CharField( verbose_name="units", max_length=10, choices=((MILLIMOLES_PER_LITER, MILLIMOLES_PER_LITER), ), null=True, blank=True, ) sodium_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) sodium_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) potassium = models.DecimalField(decimal_places=1, max_digits=2, null=True, blank=True) potassium_units = models.CharField( verbose_name="units", max_length=10, choices=((MILLIMOLES_PER_LITER, MILLIMOLES_PER_LITER), ), null=True, blank=True, ) potassium_abnormal = models.CharField( verbose_name="abnormal", choices=YES_NO, # default=NO, max_length=25, null=True, blank=True, ) potassium_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, # default=NOT_APPLICABLE, max_length=25, null=True, blank=True, ) magnesium = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) magnesium_units = models.CharField( verbose_name="units", choices=MG_MMOL_UNITS, null=True, blank=True, max_length=25, ) magnesium_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, null=True, blank=True, max_length=25) magnesium_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, null=True, blank=True, max_length=25, ) alt = models.IntegerField( validators=[MinValueValidator(1), MaxValueValidator(2999)], verbose_name="ALT", null=True, blank=True, ) alt_units = models.CharField( verbose_name="units", max_length=10, choices=((IU_LITER, IU_LITER), ), null=True, blank=True, ) alt_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) alt_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) urea = models.DecimalField(decimal_places=2, max_digits=6, null=True, blank=True) urea_units = models.CharField( verbose_name="units", choices=MG_MMOL_UNITS, max_length=25, null=True, blank=True, ) urea_abnormal = models.CharField( verbose_name="abnormal", choices=YES_NO, # default=NO, max_length=25, null=True, blank=True, ) urea_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) cd4 = models.IntegerField( verbose_name="abs CD4", validators=[MinValueValidator(0), MaxValueValidator(999)], blank=True, null=True, ) cd4_units = models.CharField( verbose_name="units", max_length=10, choices=((CELLS_PER_MILLIMETER_CUBED, CELLS_PER_MILLIMETER_CUBED), ), null=True, blank=True, ) cd4_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) cd4_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) vl = models.FloatField( verbose_name="Viral Load", validators=[MinValueValidator(0.0)], blank=True, null=True, ) vl_units = models.CharField( verbose_name="units", max_length=10, choices=((COPIES_PER_MILLILITER, COPIES_PER_MILLILITER), ), null=True, blank=True, ) vl_abnormal = models.CharField(verbose_name="abnormal", choices=YES_NO, max_length=25, null=True, blank=True) vl_reportable = models.CharField( verbose_name="reportable", choices=REPORTABLE, max_length=25, null=True, blank=True, ) results_abnormal = models.CharField( verbose_name="Are any of the above results abnormal?", choices=YES_NO, max_length=25, ) results_reportable = models.CharField( verbose_name="If any results are abnormal, are results within grade III " "or above?", max_length=25, choices=YES_NO_NA, help_text= ("If YES, this value will open Adverse Event Form.<br/><br/>" "Note: On Day 1 only abnormal bloods should not be reported as adverse" "events."), ) summary = models.TextField(null=True, blank=True) on_site = CurrentSiteManager() objects = CrfModelManager() def save(self, *args, **kwargs): self.summary = "\n".join(self.get_summary()) super().save(*args, **kwargs) def get_summary(self): registered_subject = RegisteredSubject.objects.get( subject_identifier=self.subject_visit.subject_identifier) opts = dict( gender=registered_subject.gender, dob=registered_subject.dob, report_datetime=self.subject_visit.report_datetime, ) summary = [] for field in [f.name for f in self._meta.fields]: value = getattr(self, field) grp = site_reportables.get("ambition").get(field) if value and grp: units = getattr(self, f"{field}_units") opts.update(units=units) grade = grp.get_grade(value, **opts) if grade and grade.grade: summary.append(f"{field}: {grade.description}.") elif not grade: normal = grp.get_normal(value, **opts) if not normal: summary.append(f"{field}: {value} {units} is abnormal") return summary def get_action_item_reason(self): return self.summary @property def abnormal(self): return self.results_abnormal @property def reportable(self): return self.results_reportable class Meta(CrfModelMixin.Meta): verbose_name = "Blood Result" verbose_name_plural = "Blood Results"
class Microbiology(CrfModelMixin): urine_culture_performed = models.CharField( max_length=5, choices=YES_NO, help_text="only for patients with >50 white cells in urine", ) urine_taken_date = models.DateField( validators=[date_not_before_study_start, date_not_future], null=True, blank=True) urine_culture_results = models.CharField( verbose_name="Urine culture results, if completed", max_length=10, choices=CULTURE_RESULTS, default=NOT_APPLICABLE, ) urine_culture_organism = models.CharField( verbose_name="If positive, organism", max_length=25, choices=URINE_CULTURE_RESULTS_ORGANISM, default=NOT_APPLICABLE, ) urine_culture_organism_other = OtherCharField(max_length=50, null=True, blank=True) blood_culture_performed = models.CharField(max_length=5, choices=YES_NO) blood_culture_results = models.CharField( verbose_name="Blood culture results, if completed", max_length=10, choices=CULTURE_RESULTS, default=NOT_APPLICABLE, ) blood_taken_date = models.DateField( validators=[date_not_before_study_start, date_not_future], null=True, blank=True) day_blood_taken = models.IntegerField( verbose_name="If positive, study day positive culture sample taken", validators=[MinValueValidator(1)], null=True, blank=True, ) blood_culture_organism = models.CharField( verbose_name="If growth positive, organism", max_length=50, choices=BLOOD_CULTURE_RESULTS_ORGANISM, default=NOT_APPLICABLE, ) blood_culture_organism_other = OtherCharField(max_length=50, null=True, blank=True) bacteria_identified = models.CharField( verbose_name="If bacteria, type", max_length=50, choices=BACTERIA_TYPE, default=NOT_APPLICABLE, ) bacteria_identified_other = OtherCharField(max_length=100, null=True, blank=True) sputum_afb_performed = models.CharField( verbose_name="AFB microscopy performed?", max_length=5, choices=YES_NO, help_text="Was sputum AFB done?", ) sputum_afb_date = models.DateField( validators=[date_not_before_study_start, date_not_future], null=True, blank=True) sputum_results_afb = models.CharField( verbose_name="AFB results", max_length=10, choices=POS_NEG_NA, default=NOT_APPLICABLE, ) sputum_performed = models.CharField( verbose_name="Culture performed?", max_length=15, choices=YES_NO_NA, default=NOT_APPLICABLE, ) sputum_taken_date = models.DateField( validators=[date_not_before_study_start, date_not_future], null=True, blank=True) sputum_results_culture = models.CharField( verbose_name="Culture results", max_length=10, choices=POS_NEG_NA, default=NOT_APPLICABLE, ) sputum_results_positive = models.CharField( verbose_name="If culture is positive, please specify:", max_length=50, null=True, blank=True, ) sputum_genexpert_performed = models.CharField( verbose_name="Sputum Gene-Xpert performed?", max_length=15, choices=YES_NO_NA, default=NOT_APPLICABLE, ) sputum_genexpert_date = models.DateField( verbose_name="Date sputum Gene-Xpert taken", validators=[date_not_before_study_start, date_not_future], null=True, blank=True, ) sputum_result_genexpert = models.CharField( verbose_name="Sputum Gene-Xpert results", max_length=45, choices=SPUTUM_GENEXPERT, default=NOT_APPLICABLE, ) tissue_biopsy_taken = models.CharField(max_length=5, choices=YES_NO) tissue_biopsy_results = models.CharField( verbose_name="If YES, results", max_length=10, choices=CULTURE_RESULTS, default=NOT_APPLICABLE, ) biopsy_date = models.DateField( validators=[date_not_before_study_start, date_not_future], null=True, blank=True) day_biopsy_taken = models.IntegerField( verbose_name="If positive, Study day positive culture sample taken", validators=[MinValueValidator(1)], null=True, blank=True, ) tissue_biopsy_organism = models.CharField( verbose_name="If growth positive, organism", max_length=50, choices=BIOPSY_RESULTS_ORGANISM, default=NOT_APPLICABLE, ) tissue_biopsy_organism_other = OtherCharField(max_length=50, null=True, blank=True) histopathology_report = models.TextField(null=True, blank=True) csf_genexpert_performed = models.CharField( verbose_name="CSF Gene-Xpert performed?", max_length=15, choices=YES_NO_NA, default=NOT_APPLICABLE, ) csf_genexpert_date = models.DateField( verbose_name="Date CSF Gene-Xpert taken", validators=[date_not_before_study_start, date_not_future], null=True, blank=True, ) csf_result_genexpert = models.CharField( verbose_name="CSF Gene-Xpert results", max_length=45, choices=SPUTUM_GENEXPERT, default=NOT_APPLICABLE, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "Microbiology" verbose_name_plural = "Microbiology"
class PkPdCrf(CrfModelMixin): # removed v 0.1.61 albumin = models.IntegerField(verbose_name="Albumin", null=True, blank=True, help_text="Units in g/L") amphotericin_given = models.CharField( verbose_name=("Did the patient receive any amphotericin " "formulation in the last 24 hours?"), choices=YES_NO, max_length=5, null=True, ) amphotericin_formulation = models.CharField( verbose_name=("If Yes, Which formulation of amphotericin?"), choices=AMPHOTERICIN_FORMULATION, max_length=25, blank=True, null=True, ) amphotericin_dose = models.IntegerField(verbose_name="Dose given", null=True, blank=True, help_text="Units in mg") amphotericin_started_datetime = models.DateTimeField( verbose_name="Date and time started", null=True, blank=True) amphotericin_ended_datetime = models.DateTimeField( verbose_name="Date and time stopped", null=True, blank=True) amphotericin_full_dose_given = models.CharField( verbose_name="Was the entire dose given?", choices=YES_NO, max_length=5, null=True, blank=True, ) flucytosine_dose = models.IntegerField( verbose_name="Flucytosine dose?", null=True, blank=True, help_text="Total of all doses given. Units in mg", ) flucytosine_dose_one_given = models.CharField( verbose_name="Flucytosine <b><u>DOSE 1</u></b> given? ", choices=YES_NO, max_length=5, null=True, blank=True, ) flucytosine_dose_one_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time Flucytosine <u>DOSE 1</u> was swallowed?"), null=True, blank=True, ) flucytosine_dose_one = models.IntegerField( verbose_name="Flucytosine <u>DOSE 1</u>", validators=[MinValueValidator(0), MaxValueValidator(9999)], null=True, blank=True, help_text="Units in mg", ) flucytosine_dose_two_given = models.CharField( verbose_name="Flucytosine <b><u>DOSE 2</u></b> given? ", choices=YES_NO_NA, max_length=5, null=True, blank=True, ) flucytosine_dose_two_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time Flucytosine <u>DOSE 2</u> was swallowed?"), null=True, blank=True, ) flucytosine_dose_two = models.IntegerField( verbose_name="Flucytosine <u>DOSE 2</u>", validators=[MinValueValidator(0), MaxValueValidator(9999)], null=True, blank=True, help_text="Units in mg", ) flucytosine_dose_three_given = models.CharField( verbose_name="Flucytosine <b><u>DOSE 3</u></b> given? ", choices=YES_NO_NA, max_length=5, null=True, blank=True, ) flucytosine_dose_three_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time Flucytosine <u>DOSE 3</u> was swallowed?"), null=True, blank=True, ) flucytosine_dose_three = models.IntegerField( verbose_name="Flucytosine <u>DOSE 3</u>", validators=[MinValueValidator(0), MaxValueValidator(9999)], null=True, blank=True, help_text="Units in mg", ) flucytosine_dose_four_given = models.CharField( verbose_name="Flucytosine <b><u>DOSE 4</u></b> given? ", choices=YES_NO_NA, max_length=5, null=True, blank=True, ) flucytosine_dose_four_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time Flucytosine <u>DOSE 4</u> was swallowed?"), null=True, blank=True, ) flucytosine_dose_four = models.IntegerField( verbose_name="Flucytosine <u>DOSE 4</u>", validators=[MinValueValidator(0), MaxValueValidator(9999)], null=True, blank=True, help_text="Units in mg", ) flucytosine_dose_reason_missed = models.TextField( verbose_name="If any Flucytosine doses not given, provide reason", max_length=75, null=True, blank=True, ) fluconazole_dose = models.IntegerField(verbose_name="Fluconazole dose?", null=True, blank=True, help_text="Units in mg") fluconazole_dose_given = models.CharField( verbose_name="Was the Fluconazole dose given?", choices=YES_NO_NA, default=NOT_APPLICABLE, max_length=11, null=True, ) fluconazole_dose_datetime = models.DateTimeField( verbose_name="Date and time Fluconazole was swallowed?", null=True, blank=True) fluconazole_dose_reason_missed = models.TextField( verbose_name="If Fluconazole dose not given, provide reason", max_length=75, null=True, blank=True, ) blood_sample_one_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 1</u> taken?"), null=True, blank=True, ) blood_sample_two_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 2</u> taken?"), null=True, blank=True, ) blood_sample_three_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 3</u> taken?"), null=True, blank=True, ) blood_sample_four_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 4</u> taken?"), null=True, blank=True, ) blood_sample_five_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 5</u> taken?"), null=True, blank=True, ) blood_sample_six_datetime = models.DateTimeField( verbose_name=mark_safe( "Date and time blood <u>SAMPLE 6</u> taken?"), null=True, blank=True, ) blood_sample_missed = models.CharField( verbose_name="Were any blood samples missed?", choices=YES_NO, max_length=5, null=True, blank=True, ) blood_sample_reason_missed = models.TextField( verbose_name="If any blood samples missed, provide reason", max_length=75, null=True, blank=True, ) pre_dose_lp = models.CharField( verbose_name="Is this a pre-dose LP?", choices=YES_NO, max_length=5, null=True, blank=True, ) post_dose_lp = models.CharField( verbose_name="Is this a post-dose LP?", choices=YES_NO, max_length=5, null=True, blank=True, ) time_csf_sample_taken = models.DateTimeField( verbose_name="What date and time was the CSF sample taken?", null=True, blank=True, ) on_site = CurrentSiteManager() objects = CrfModelManager() history = HistoricalRecords() class Meta(CrfModelMixin.Meta): verbose_name = "PK/PD" verbose_name_plural = "PK/PD"