class InfantMusculoskeletal(BaseCnsItem): musculo_skeletal = models.CharField( max_length=250, choices=MUSCULOSKELETAL_ABNORMALITY, verbose_name="Musculo-skeletal abnomalities", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) musculo_skeletal_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantMusculoskeletalManager() history = AuditTrail() def natural_key(self): return (self.musculo_skeletal, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies: Musculo-sk" unique_together = ('musculo_skeletal', 'congenital_anomalies')
class HeartAttack(BaseScheduledVisitModel): """A model completed by the user to record any heart conditions in the past 12 months.""" CONSENT_MODEL = SubjectConsent date_heart_attack = models.DateField( verbose_name="Date of the heart disease or stroke diagnosis:", validators=[date_not_future], help_text="", ) dx_heart_attack = models.ManyToManyField( HeartDisease, verbose_name= "[Interviewer:] What is the heart disease or stroke diagnosis as recorded?", help_text=("(tick all that apply)"), ) dx_heart_attack_other = OtherCharField() history = AuditTrail() class Meta: app_label = 'bcpp_subject' verbose_name = "Heart Attack or Stroke" verbose_name_plural = "Heart Attack or Stroke"
class MaternalArvPostAdh(MaternalCrfModel): """Maternal ARV adherence post-partum""" missed_doses = models.IntegerField(verbose_name=( "Since the last attended last scheduled visit, how many doses of" " triple ARVs were missed? ")) missed_days = models.IntegerField(verbose_name=( "Since the last attended scheduled visit, how many entire days" " were triple ARVS not taken?"), default=0) missed_days_discnt = models.IntegerField(verbose_name=( "If triple ARVs discontinued by health provider, how many days were triple ARVs missed" " prior to discontinuation?"), default=0) comment = models.TextField(max_length=250, verbose_name="Comment", blank=True, null=True) history = AuditTrail() class Meta: app_label = 'mb_maternal' verbose_name = "Maternal ARVs Post: Adherence" verbose_name_plural = "Maternal ARVs Post: Adherence"
class PregnantFollowup (BaseScheduledModel): """Permission to contact for follow up for pregnant women""" contact_consent = models.CharField( verbose_name=_("It is recommended that pregnant women receive antenatal care for their health" " and their baby\'s health. This care includes an HIV test during the third" " trimester of pregnancy. Counselors are available to help you receive HIV" " testing during pregnancy. Do you give permission for counselors to contact" " you by telephone and home visits?"), max_length=3, choices=YES_NO, help_text='', ) contact_family = models.CharField( verbose_name=_("If we are unable to reach you, would you be willing to have me or one of my" " fellow counselors contact a family member or friend who would be able to reach you?"), max_length=3, choices=YES_NO, help_text='', ) history = AuditTrail() class Meta: app_label = 'bcpp_htc_subject' verbose_name = "Pregnant Follow-up" verbose_name_plural = "Pregnant Follow-up"
class MaternalLabDelDxT(CrfInlineModelMixin, SyncModelMixin, BaseUuidModel): """ Diagnosis during pregnancy collected during labor and delivery (transactions). """ maternal_lab_del_dx = models.OneToOneField(MaternalLabDelDx) lab_del_dx = models.CharField(verbose_name="Diagnosis", max_length=175, choices=DX_MATERNAL) lab_del_dx_specify = models.CharField( verbose_name="Diagnosis specification", max_length=50, blank=True, null=True) grade = models.IntegerField(verbose_name="Grade") hospitalized = models.CharField(verbose_name="Hospitalized", max_length=3, choices=YES_NO) objects = MaternalLabDelDxTManager() history = AuditTrail() class Meta: app_label = 'mb_maternal' verbose_name = "Delivery: Preg DxT" verbose_name_plural = "Delivery: Preg DxT"
class InfantVaccines(CrfInlineModelMixin, SyncModelMixin, ExportTrackingFieldsMixin, BaseUuidModel): infant_birth_feed_vaccine = models.ForeignKey(InfantBirthFeedVaccine) vaccination = models.CharField( choices=INFANT_VACCINATIONS, verbose_name= "Since delivery, did the child receive any of the following vaccinations", max_length=100) vaccine_date = models.DateField(verbose_name='Date Vaccine was given', null=True, blank=True) objects = InfantVaccinesManager() history = AuditTrail() def natural_key(self): return ( self.vaccination, ) + self.infant_birth_feed_vaccine.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Infant Vaccines" verbose_name_plural = "Infant Vaccines" unique_together = ('infant_birth_feed_vaccine', 'vaccination', 'vaccine_date')
class HtcSubjectVisit(BaseVisitTracking): household_member = models.ForeignKey(HouseholdMember) reason_unscheduled = models.CharField( verbose_name="If 'Unscheduled' above, provide reason for the unscheduled visit", max_length=25, blank=True, null=True, choices=VISIT_UNSCHEDULED_REASON, ) history = AuditTrail() def save(self, *args, **kwargs): self.info_source = 'subject' self.reason = 'consent' super(HtcSubjectVisit, self).save(*args, **kwargs) def __unicode__(self): return unicode(self.appointment) def dispatch_container_lookup(self): return (('bcpp_household', 'Household'), 'household_member__household_structure__household__household_identifier') class Meta: app_label = "bcpp_htc_subject" verbose_name = "HTC Subject Visit"
class MaternalArvPreg(MaternalCrfModel): """ This model is for all HIV positive mothers who are pregnant (whom we hope to enroll their infant) and/or for mothers who have just delivered """ took_arv = models.CharField( max_length=3, choices=YES_NO, verbose_name="Did the mother receive any ARVs during this pregnancy?", help_text="(NOT including single -dose NVP in labour)") is_interrupt = models.CharField( max_length=3, choices=YES_NO, verbose_name= "Was there an interruption in the ARVs received during pregnancy through delivery of >/=3days?", ) interrupt = models.CharField( verbose_name="Please give reason for interruption", max_length=50, choices=ARV_INTERRUPTION_REASON, default=NOT_APPLICABLE) interrupt_other = models.TextField(max_length=250, verbose_name="Other, specify ", blank=True, null=True) history = AuditTrail() class Meta: app_label = 'mb_maternal' verbose_name = 'Maternal ARV In This Preg' verbose_name_plural = 'Maternal ARV In This Preg'
class MaternalArv(CrfInlineModelMixin, SyncModelMixin, BaseUuidModel): """ ARV table to indicate ARV medication taken by mother """ maternal_arv_preg = models.ForeignKey(MaternalArvPreg) arv_code = models.CharField(verbose_name="ARV code", max_length=35, choices=ARV_DRUG_LIST) start_date = models.DateField(verbose_name="Date Started", null=True, blank=False) stop_date = models.DateField(verbose_name="Date Stopped", null=True, blank=True) objects = MaternalArvManager() history = AuditTrail() def natural_key(self): return (self.arv_code, ) + self.maternal_arv_preg.natural_key() class Meta: app_label = 'mb_maternal' verbose_name = 'Maternal ARV' verbose_name_plural = 'Maternal ARV' unique_together = ('maternal_arv_preg', 'arv_code')
class InfantOtherAbnormalityItems(BaseCnsItem): other_abnormalities = models.CharField( max_length=250, choices=OTHER_DEFECT, verbose_name="Other", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) other_abnormalities_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantOtherAbnormalityItemsManager() history = AuditTrail() def natural_key(self): return (self.other_abnormalities, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies: Other" unique_together = ('other_abnormalities', 'congenital_anomalies')
class InfantFacialDefect(BaseCnsItem): facial_defect = models.CharField( max_length=250, choices=FACIAL_DEFECT, verbose_name="Facial defects", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) facial_defects_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantFacialDefectManager() history = AuditTrail() def natural_key(self): return (self.facial_defect, ) + self. congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies:Facial" unique_together = ('facial_defect', 'congenital_anomalies')
class InfantTrisomies(BaseCnsItem): trisomies = models.CharField( max_length=250, choices=TRISOME_CHROSOMESOME_ABNORMALITY, verbose_name="Trisomies / chromosomes abnormalities", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) trisomies_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantTrisomiesManager() history = AuditTrail() def natural_key(self): return (self.trisomies, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies: Trisomes" unique_together = ('trisomies', 'congenital_anomalies')
class InfantCns(BaseCnsItem): cns = models.CharField( max_length=250, choices=CNS_ABNORMALITIES, verbose_name="Central nervous system abnormality", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) cns_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantCnsManager() history = AuditTrail() def natural_key(self): return (self.cns, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies:Cns" unique_together = ('cns', 'congenital_anomalies')
class InfantSkin(BaseCnsItem): skin = models.CharField( max_length=250, choices=SKIN_ABNORMALITY, verbose_name="Skin abnormalities", help_text="Excludes cafe au lait spots, Mongolian spots, port wine stains, " "nevus, hemangloma <4 cm in diameter. If hemangloma is >4 cm, specify", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) skin_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantSkinManager() history = AuditTrail() def natural_key(self): return (self.skin, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies: Skin" unique_together = ('skin', 'congenital_anomalies')
class RapidTestResult(MaternalCrfModel): """ A model completed by the user on the mother's rapid test result. """ rapid_test_done = models.CharField( verbose_name="Was a rapid test processed?", choices=YES_NO, max_length=3) result_date = models.DateField(verbose_name="Date of rapid test", null=True, blank=True) result = models.CharField(verbose_name="What is the rapid test result?", choices=POS_NEG, null=True, blank=True, max_length=15) comments = models.CharField(verbose_name="Comment", max_length=250, blank=True, null=True) history = AuditTrail() def get_result_datetime(self): return self.report_datetime def get_test_code(self): return 'HIV' class Meta: app_label = 'mb_maternal' verbose_name = 'Rapid Test Result' verbose_name_plural = 'Rapid Test Result'
class MaternalEligibilityLoss(SyncModelMixin, ExportTrackingFieldsMixin, BaseUuidModel): """ A model triggered and completed by system when a mother is in-eligible. """ maternal_eligibility = models.OneToOneField(MaternalEligibility, null=True) report_datetime = models.DateTimeField( verbose_name="Report Date and Time", default=timezone.now, help_text='Date and time of report.') reason_ineligible = models.TextField( verbose_name='Reason not eligible', max_length=500, help_text='Gets reasons from Maternal Eligibility.ineligibility') objects = MaternalEligibilityLossManager() history = AuditTrail() def natural_key(self): return ( self.maternal_eligibility.natural_key(), self.report_datetime, ) def ineligibility(self): return self.reason_ineligible or [] reason_ineligible.allow_tags = True class Meta: app_label = 'mb_maternal' verbose_name = 'Maternal Eligibility Loss' verbose_name_plural = 'Maternal Eligibility Loss'
class InfantFuDxItems(CrfInlineModelMixin, SyncModelMixin, BaseUuidModel): infant_fu_dx = models.ForeignKey(InfantFuDx) fu_dx = models.CharField(verbose_name="Diagnosis", max_length=150, choices=DX_INFANT) fu_dx_specify = models.CharField(verbose_name="Diagnosis specification", max_length=50, blank=True, null=True) health_facility = models.CharField( verbose_name="Seen at health facility for Dx", choices=YES_NO, max_length=3) was_hospitalized = models.CharField(verbose_name="Hospitalized?", choices=YES_NO, max_length=3) objects = InfantFuDxItemsManager() history = AuditTrail() def natural_key(self): return (self.fu_dx, ) + self.infant_fu_dx.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Infant FollowUp: Dx" unique_together = ('fu_dx', 'infant_fu_dx')
class MaleFollowup(BaseScheduledModel): """Male Permissions to be contacted for follow-up""" contact_consent = models.CharField( verbose_name= _("My fellow counselors and I are available to help you decide if circumcision" " is right for you and to access male circumcision services. If we try to" " call you and miss you, the caller will not leave any detailed message but" " only his name and number. If someone asks, we will just say we are doing" " mobilization for men\'s health. Do you give permission for counselors" " to contact you by telephone and home visits?"), max_length=3, choices=YES_NO, help_text='', ) contact_family = models.CharField( verbose_name= _("If we are unable to reach you, would you be willing to have me or one" " of my fellow counselors contact a family member or friend who would be" " able to reach you? The caller will not leave any detailed message but" " only his name and number."), max_length=3, choices=YES_NO, help_text='', ) history = AuditTrail() class Meta: app_label = 'bcpp_htc_subject' verbose_name = "Male Follow-up" verbose_name_plural = "Male Follow-up"
class MaternalRequisition(CrfModelMixin, RequisitionModelMixin, SyncModelMixin, ExportTrackingFieldsMixin, BaseUuidModel): aliquot_model = Aliquot maternal_visit = models.ForeignKey(MaternalVisit) packing_list = models.ForeignKey(PackingList, null=True, blank=True) aliquot_type = models.ForeignKey(AliquotType) panel = models.ForeignKey(Panel) objects = MaternalRequisitionManager() history = AuditTrail() entry_meta_data_manager = RequisitionMetaDataManager(MaternalVisit) def __unicode__(self): return '{0} {1}'.format(unicode(self.panel), self.requisition_identifier) def natural_key(self): return (self.requisition_identifier,) class Meta: app_label = 'mb_lab' verbose_name = 'Maternal Requisition' verbose_name_plural = 'Maternal Requisition' unique_together = ('maternal_visit', 'panel', 'is_drawn') ordering = ('-created', )
class InfantRequisition(CrfModelMixin, RequisitionModelMixin, SyncModelMixin, ExportTrackingFieldsMixin, BaseUuidModel): aliquot_model = Aliquot infant_visit = models.ForeignKey(InfantVisit) packing_list = models.ForeignKey(PackingList, null=True, blank=True) aliquot_type = models.ForeignKey(AliquotType) panel = models.ForeignKey(Panel) objects = InfantRequisitionManager() history = AuditTrail() entry_meta_data_manager = RequisitionMetaDataManager(InfantVisit) def get_visit(self): return self.infant_visit class Meta: app_label = 'mb_lab' verbose_name = 'Infant Laboratory Requisition' verbose_name_plural = 'Infant Laboratory Requisition' unique_together = ('infant_visit', 'panel', 'is_drawn')
class HtcCircumcision(BaseScheduledModel): is_circumcised = models.CharField( verbose_name=_("Male circumcision is the removal of the foreskin of " "the penis. Here is a diagram to clarify what a " "circumcised and uncircumcised man looks like. " "Are you circumcised? "), max_length=3, choices=YES_NO, help_text="", ) circumcision_year = models.DateField( verbose_name=_("What year were you circumcised? "), null=True, blank=True, help_text="", ) history = AuditTrail() class Meta: app_label = 'bcpp_htc_subject' verbose_name = "HTC Circumcision" verbose_name_plural = "HTC Circumcision"
class FollowUpList(BaseSyncUuidModel): household_structure = models.ForeignKey(HouseholdStructure) community = models.CharField(max_length=50) attempts = models.IntegerField(default=0) outcome = models.TextField(max_length=150, ) status = models.CharField( max_length=15, choices=( (NEW, 'New'), (OPEN, 'Open'), (CLOSED, 'Closed'), ), default=NEW, ) label = models.CharField( max_length=25, null=True, help_text="label to group reasons for contact, e.g. T1 preparation") history = AuditTrail() class Meta: app_label = 'bcpp_household' unique_together = ['household_structure', 'label']
class MaternalLabDelDx(MaternalCrfModel): """ Diagnosis during pregnancy collected during labor and delivery. This is for HIV positive mothers only""" has_who_dx = models.CharField(verbose_name=( "During this pregnancy, did the mother have any new diagnoses " "listed in the WHO Adult/Adolescent HIV clinical staging document which " "is/are NOT reported?"), max_length=3, choices=YES_NO_NA) who = models.ManyToManyField( WcsDxAdult, verbose_name= "List any new WHO Stage III/IV diagnoses that are not reported in Question 3 below: " ) has_preg_dx = models.CharField( verbose_name= "During this pregnancy, did the mother have any of the following diagnoses? ", max_length=3, choices=YES_NO, help_text= "If yes, Select all that apply in the table, only report grade 3 or 4 diagnoses" ) history = AuditTrail() class Meta: app_label = 'mb_maternal' verbose_name = "Delivery: Preg Dx" verbose_name_plural = "Delivery: Preg Dx"
class VaccinesReceived(CrfInlineModelMixin, ExportTrackingFieldsMixin, SyncModelMixin, BaseUuidModel): """ALL possible vaccines given to infant""" infant_fu_immunizations = models.ForeignKey(InfantFuImmunizations) received_vaccine_name = models.CharField( verbose_name="Received vaccine name", choices=IMMUNIZATIONS, max_length=100) date_given = models.DateField(verbose_name="Date Given", null=True, blank=True) infant_age = models.CharField(verbose_name="Infant age when vaccine given", choices=INFANT_AGE_VACCINE_GIVEN, null=True, blank=True, max_length=35) objects = VaccinesReceivedManager() history = AuditTrail() def natural_key(self): return (self.received_vaccine_name, ) + self.infant_fu_immunizations.natural_key() class Meta: app_label = 'mb_infant' verbose_name = 'Received Vaccines' verbose_name_plural = 'Received Vaccines' unique_together = ('received_vaccine_name', 'infant_fu_immunizations', 'date_given')
class ReplacementHistory(BaseDispatchSyncUuidModel, BaseSyncUuidModel): """A system model that tracks replaced, and replaced by, plots and households.""" replacing_item = models.CharField( verbose_name='Replaced by', max_length=25, ) replaced_item = models.CharField( verbose_name='Replaced item', max_length=25, ) replacement_datetime = models.DateTimeField() replacement_reason = models.CharField( verbose_name='Reason for replacement', max_length=100, help_text="Reasons could be absentees, refusals, e.t.c", ) history = AuditTrail() objects = ReplacementHistoryManager() def natural_key(self): return (self.replacing_item, self.replaced_item) class Meta: app_label = 'bcpp_household' ordering = ['-replacing_item', ] unique_together = ('replacing_item', 'replaced_item')
class VaccinesMissed(CrfInlineModelMixin, ExportTrackingFieldsMixin, SyncModelMixin, BaseUuidModel): """ALL vaccines missed by infant""" parent_model_attr = 'infant_fu_immunizations' infant_fu_immunizations = models.ForeignKey(InfantFuImmunizations) missed_vaccine_name = models.CharField(verbose_name="Missed vaccine name", choices=IMMUNIZATIONS, max_length=100) reason_missed = models.CharField( verbose_name="Reasons infant missed vaccines", choices=REASONS_VACCINES_MISSED, max_length=100, null=True, blank=True) reason_missed_other = OtherCharField() objects = VaccinesMissedManager() history = AuditTrail() def natural_key(self): return (self.missed_vaccine_name, ) + self.infant_fu_immunizations.natural_key() class Meta: app_label = 'mb_infant' verbose_name = 'Missed Vaccines' verbose_name_plural = 'Missed Vaccines' unique_together = ('missed_vaccine_name', 'infant_fu_immunizations')
class SubjectUndecidedEntry(BaseSubjectEntry): """A model completed by the user that captures information on the undecided status of a household member potentially eligible for BHS.""" subject_undecided = models.ForeignKey(SubjectUndecided) subject_undecided_reason = models.CharField(verbose_name="Reason", max_length=100, choices=UNDECIDED_REASON) history = AuditTrail() objects = SubjectUndecidedEntryManager() def save(self, *args, **kwargs): if self.subject_undecided.household_member.household_structure.household.replaced_by: raise AlreadyReplaced( 'Model {0}-{1} has its container replaced.'.format( self._meta.object_name, self.pk)) super(SubjectUndecidedEntry, self).save(*args, **kwargs) @property def inline_parent(self): return self.subject_undecided def natural_key(self): return (self.report_datetime, ) + self.subject_undecided.natural_key() natural_key.dependencies = ['bcpp_subject.subjectundecided'] class Meta: app_label = 'bcpp_household_member' verbose_name = "Subject Undecided Entry" verbose_name_plural = "Subject Undecided Entries" unique_together = ('subject_undecided', 'report_datetime')
class SubjectUndecided(BaseMemberStatusModel): """A system model that links "undecided" information to a household member.""" history = AuditTrail() def save(self, *args, **kwargs): if self.household_member.household_structure.household.replaced_by: raise AlreadyReplaced('Household {0} replaced.'.format( self.subject_undecided.household_member.household_structure. household.household_identifier)) self.survey = self.household_member.survey self.registered_subject = self.household_member.registered_subject try: update_fields = kwargs.get('update_fields') + [ 'registered_subject', 'survey' ] kwargs.update({'update_fields': update_fields}) except TypeError: pass super(SubjectUndecided, self).save(*args, **kwargs) def deserialize_prep(self, **kwargs): # SubjectUndecided being deleted by an IncommingTransaction, we go ahead and delete it. # This happens when we switch status from absentee and there are no absentee entries # attached to this SubjectUndecided. if kwargs.get('action', None) and kwargs.get('action', None) == 'D': self.delete() class Meta: app_label = 'bcpp_household_member' verbose_name = "Subject Undecided" verbose_name_plural = "Subject Undecided" unique_together = ( 'registered_subject', 'survey', )
class MaternalArvPostMod(CrfInlineModelMixin, SyncModelMixin, BaseUuidModel): """ Maternal ARV modifications post-partum. if art_status never, no_mod or N/A then this is not required""" maternal_arv_post = models.ForeignKey(MaternalArvPost) arv_code = models.CharField(verbose_name="ARV Code", max_length=25, choices=ARV_DRUG_LIST) dose_status = models.CharField(max_length=25, choices=DOSE_STATUS, verbose_name="Dose Status") modification_date = models.DateField(verbose_name="Date ARV Modified") modification_code = models.CharField( max_length=50, choices=ARV_MODIFICATION_REASON, verbose_name="Reason for Modification") objects = MaternalArvPostModManager() history = AuditTrail() class Meta: app_label = 'mb_maternal' verbose_name = 'Maternal ARVs Post: Mods' verbose_name_plural = 'Maternal ARVs Post: Mods' unique_together = ('maternal_arv_post', 'arv_code', 'modification_date')
class InfantRenal(BaseCnsItem): renal = models.CharField( max_length=250, choices=RENAL_ANOMALY, verbose_name="Renal anomalies", ) abnormality_status = models.CharField( max_length=35, choices=CONFIRMED_SUSPECTED, verbose_name="Abnormality status", ) renal_other = OtherCharField( max_length=250, verbose_name="if other specify...", blank=True, null=True, ) objects = InfantRenalManager() history = AuditTrail() def natural_key(self): return (self.renal, ) + self.congenital_anomalies.natural_key() class Meta: app_label = 'mb_infant' verbose_name = "Congenital Anomalies: Renal" unique_together = ('renal', 'congenital_anomalies')