Пример #1
0
class CrfModelMixin(CrfNoManagerModelMixin):

    on_site = CurrentSiteManager()
    objects = CrfModelManager()
    history = HistoricalRecords(inherit=True)

    class Meta(CrfNoManagerModelMixin.Meta):
        abstract = True
Пример #2
0
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'
Пример #3
0
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"
Пример #4
0
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)'
Пример #5
0
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"
Пример #6
0
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
Пример #7
0
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"
Пример #8
0
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'
Пример #9
0
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"
Пример #12
0
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"
Пример #13
0
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"
Пример #14
0
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"
Пример #15
0
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&nbsp;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&nbsp;1</u> was swallowed?'),
        null=True,
        blank=True)

    flucytosine_dose_two_given = models.CharField(
        verbose_name='Flucytosine <u>DOSE&nbsp;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&nbsp;2</u> was swallowed?'),
        null=True,
        blank=True)

    flucytosine_dose_three_given = models.CharField(
        verbose_name='Flucytosine <u>DOSE&nbsp;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&nbsp;3</u> was swallowed?'),
        null=True,
        blank=True)

    flucytosine_dose_four_given = models.CharField(
        verbose_name='Flucytosine <u>DOSE&nbsp;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&nbsp;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&nbsp;1</u> taken?'),
                                                     null=True,
                                                     blank=True)

    blood_sample_two_datetime = models.DateTimeField(verbose_name=mark_safe(
        'Date and time blood <u>SAMPLE&nbsp;2</u> taken?'),
                                                     null=True,
                                                     blank=True)

    blood_sample_three_datetime = models.DateTimeField(verbose_name=mark_safe(
        'Date and time blood <u>SAMPLE&nbsp;3</u> taken?'),
                                                       null=True,
                                                       blank=True)

    blood_sample_four_datetime = models.DateTimeField(verbose_name=mark_safe(
        'Date and time blood <u>SAMPLE&nbsp;4</u> taken?'),
                                                      null=True,
                                                      blank=True)

    blood_sample_five_datetime = models.DateTimeField(verbose_name=mark_safe(
        'Date and time blood <u>SAMPLE&nbsp;5</u> taken?'),
                                                      null=True,
                                                      blank=True)

    blood_sample_six_datetime = models.DateTimeField(verbose_name=mark_safe(
        'Date and time blood <u>SAMPLE&nbsp;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"
Пример #17
0
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'
Пример #18
0
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'
Пример #19
0
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'
Пример #20
0
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'
Пример #21
0
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"
Пример #22
0
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"
Пример #23
0
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"
Пример #24
0
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&nbsp;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&nbsp;1</u> was swallowed?"),
        null=True,
        blank=True,
    )

    flucytosine_dose_one = models.IntegerField(
        verbose_name="Flucytosine <u>DOSE&nbsp;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&nbsp;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&nbsp;2</u> was swallowed?"),
        null=True,
        blank=True,
    )

    flucytosine_dose_two = models.IntegerField(
        verbose_name="Flucytosine <u>DOSE&nbsp;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&nbsp;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&nbsp;3</u> was swallowed?"),
        null=True,
        blank=True,
    )

    flucytosine_dose_three = models.IntegerField(
        verbose_name="Flucytosine <u>DOSE&nbsp;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&nbsp;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&nbsp;4</u> was swallowed?"),
        null=True,
        blank=True,
    )

    flucytosine_dose_four = models.IntegerField(
        verbose_name="Flucytosine <u>DOSE&nbsp;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&nbsp;1</u> taken?"),
        null=True,
        blank=True,
    )

    blood_sample_two_datetime = models.DateTimeField(
        verbose_name=mark_safe(
            "Date and time blood <u>SAMPLE&nbsp;2</u> taken?"),
        null=True,
        blank=True,
    )

    blood_sample_three_datetime = models.DateTimeField(
        verbose_name=mark_safe(
            "Date and time blood <u>SAMPLE&nbsp;3</u> taken?"),
        null=True,
        blank=True,
    )

    blood_sample_four_datetime = models.DateTimeField(
        verbose_name=mark_safe(
            "Date and time blood <u>SAMPLE&nbsp;4</u> taken?"),
        null=True,
        blank=True,
    )

    blood_sample_five_datetime = models.DateTimeField(
        verbose_name=mark_safe(
            "Date and time blood <u>SAMPLE&nbsp;5</u> taken?"),
        null=True,
        blank=True,
    )

    blood_sample_six_datetime = models.DateTimeField(
        verbose_name=mark_safe(
            "Date and time blood <u>SAMPLE&nbsp;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"