def child_age(self): if self.get_assent: birth_date = self.get_assent.dob years = age(birth_date, get_utcnow()).years return years else: childconsent = self.child_consent birth_date = childconsent.child_dob if birth_date: years = age(birth_date, get_utcnow()).years return years
def child_age(self): if self.child_assent_obj: birth_date = self.child_assent_obj.dob years = age(birth_date, get_utcnow()).years return years elif self.child_caregiver_consent_obj: birth_date = self.child_caregiver_consent_obj.child_dob years = age(birth_date, get_utcnow()).years return years elif self.maternal_delivery_obj: birth_date = self.maternal_delivery_obj.delivery_datetime.date() years = age(birth_date, get_utcnow()).months return years return 0
def child_gt10(self, visit): onschedule_model = django_apps.get_model( visit.appointment.schedule.onschedule_model) child_subject_identifier = None try: onschedule_obj = onschedule_model.objects.get( subject_identifier=visit.appointment.subject_identifier, schedule_name=visit.appointment.schedule_name) except onschedule_model.DoesNotExist: pass else: if 'antenatal' not in onschedule_obj.schedule_name: child_subject_identifier = onschedule_obj.child_subject_identifier if child_subject_identifier and not self.is_child_offstudy( child_subject_identifier): registered_model = django_apps.get_model( f'edc_registration.registeredsubject') try: registered_child = registered_model.objects.get( subject_identifier=child_subject_identifier) except registered_model.DoesNotExist: raise else: child_age = age(registered_child.dob, visit.report_datetime) child_age = float(f'{child_age.years}.{child_age.months}') if (child_age <= 15.9 and child_age >= 10): return [True, child_subject_identifier] return [False, child_subject_identifier]
def age(self): consent_datetime = self.cleaned_data.get( 'consent_datetime', self.instance.consent_datetime) dob = self.cleaned_data.get('dob') if consent_datetime and dob: return age(dob, consent_datetime.date()) return None
def common_clean(self): if not self.household_member.eligible_member: raise MemberEnrollmentError( 'Member is not eligible for screening.') # compare values to member, raise where they dont match if self.dob: try: age_in_years = age(self.dob, self.report_datetime).years except AgeValueError as e: raise MemberEnrollmentError({'dob': str(e)}) if age_in_years != self.household_member.age_in_years: raise MemberEnrollmentError( 'Age does not match member\'s age. Expected {}. Got {}'. format(self.household_member.age_in_years, age_in_years), 'dob') if self.part_time_resident: if self.household_member.study_resident != self.part_time_resident: raise MemberEnrollmentError( 'Residency does not match member\'s residency. Expected {}' .format( self.household_member.get_study_resident_display()), 'part_time_resident') if self.initials: if self.household_member.initials != self.initials: raise MemberEnrollmentError( 'Initials do not match member\'s initials. Expected {}'. format(self.household_member.initials), 'initials') if self.gender: if self.household_member.gender != self.gender: raise MemberEnrollmentError( 'Gender does not match member\'s gender. Expected {}'. format(self.household_member.get_gender_display()), 'gender') super().common_clean()
def save(self, *args, **kwargs): if self.dob: self.age_in_years = age(self.dob, self.report_datetime).years # is eligible or collect reasons not eligible, but do not raise an # exception loss_reason = [] if self.has_identity == NO: loss_reason.append('No valid identity.') if self.household_residency == NO and not self.household_member.cloned: loss_reason.append('Failed household residency requirement') if self.part_time_resident == NO and not self.household_member.cloned: loss_reason.append( 'Does not spend 3 or more nights per month in the community.') if self.citizen == NO and self.legal_marriage == NO: loss_reason.append('Not a citizen and not married to a citizen.') self.non_citizen = True if (self.citizen == NO and self.legal_marriage == YES and self.marriage_certificate == NO): loss_reason.append( 'Not a citizen, married to a citizen but does not ' 'have a marriage certificate.') self.non_citizen = True if self.literacy == NO: loss_reason.append('Illiterate with no literate witness.') age_helper = self.age_helper_cls( age_in_years=self.household_member.age_in_years) if age_helper.is_minor and self.guardian != YES: loss_reason.append('Minor without guardian available.') if self.confirm_participation == BLOCK_PARTICIPATION: loss_reason.append('Already enrolled.') self.is_eligible = False if loss_reason else True self.loss_reason = '|'.join(loss_reason) if loss_reason else None super().save(*args, **kwargs)
def validate_child_years_more_tha_12yrs_at_jun_2025(self, cleaned_data): child_dob = cleaned_data.get('child_dob') if child_dob: date_jun_2025 = datetime.datetime.strptime("2025-01-30", "%Y-%m-%d").date() child_dob = datetime.datetime.strptime(child_dob, "%Y-%m-%d").date() child_age_at_2025 = age(child_dob, date_jun_2025).years if cleaned_data.get('gender') == 'F': if (child_age_at_2025 < 12 and cleaned_data.get('child_preg_test') != NOT_APPLICABLE): msg = { 'child_preg_test': 'Child will not be 12 years old by 2025, This field is ' 'not applicable' } self._errors.update(msg) raise ValidationError(msg) elif (child_age_at_2025 >= 12 and cleaned_data.get('child_preg_test') == NOT_APPLICABLE): msg = { 'child_preg_test': 'Child is Female. This field is applicable' } self._errors.update(msg) raise ValidationError(msg)
def child_age(self): years = None if self.object.child_dob: birth_date = self.object.child_dob child_age = age(birth_date, get_utcnow()) months = 0 if child_age.years > 0: months = child_age.years * 12 years = round((months + child_age.months) / 12, 2) return years if years else 0
def get_age(context, born=None): if born: reference_datetime = context.get('reference_datetime', get_utcnow()) participant_age = age(born, reference_datetime) age_str = '' age_months = participant_age.months % 12 if participant_age.years > 0: age_str += str(participant_age.years) + ' yrs ' if age_months > 0: age_str += str(age_months) + ' months' return age_str
def get_child_age(self, visit=None, **kwargs): """Returns child age """ if not self.mother_pregnant(visit=visit): caregiver_child_consent_cls = django_apps.get_model( f'{self.maternal_app_label}.caregiverchildconsent') consents = caregiver_child_consent_cls.objects.filter( subject_identifier=visit.subject_identifier) if consents: caregiver_child_consent = consents.latest('consent_datetime') return age(caregiver_child_consent.child_dob, visit.report_datetime)
def age_at_enrollment(self, child_dob=None, check_date=None): """Returns age months as decimals. """ child_dob = child_dob or self.child_dob check_date = check_date or self.enrollment_date if check_date > child_dob: child_age = age(child_dob, check_date) child_age = str(child_age.years) + '.' + str(child_age.months) else: child_age = 0 return float(child_age)
def validate_age(self): cleaned_data = self.cleaned_data if cleaned_data.get('dob'): try: age_in_years = age( cleaned_data.get('dob'), cleaned_data.get('report_datetime')).years except AgeValueError as e: raise forms.ValidationError({'dob': str(e)}) age_helper = self.age_helper_cls( age_in_years=age_in_years, **cleaned_data) age_helper.validate_or_raise()
def func_12_years_older_female(self, visit=None, **kwargs): """Returns true if participant is 12 years or older """ assent_model = django_apps.get_model(f'{self.app_label}.childassent') assent_objs = assent_model.objects.filter( subject_identifier=visit.subject_identifier) if assent_objs: assent_obj = assent_objs.latest('consent_datetime') child_age = age(assent_obj.dob, get_utcnow()) return child_age.years >= 12 and assent_obj.gender == FEMALE
def test_consent_validates_with_minor_dob(self): household_structure = self.make_household_ready_for_enumeration() household_member = HouseholdMember.objects.get( household_structure=household_structure) enrollment_checklist = self.add_enrollment_checklist(household_member) age_in_years = age( enrollment_checklist.dob, enrollment_checklist.report_datetime).years test_dob = enrollment_checklist.dob - \ relativedelta(years=(age_in_years - 17)) self.assertRaises( ConsentValidationError, self.add_subject_consent, household_member=household_member, consent_datetime=enrollment_checklist.report_datetime, dob=test_dob)
def child_assent_on_post_save(sender, instance, raw, created, **kwargs): """Put subject on schedule after consenting. """ age_in_years = age(instance.dob, get_utcnow()).years if not raw and instance.is_eligible: if age_in_years >= 7: caregiver_child_consent_cls = django_apps.get_model( 'flourish_caregiver.caregiverchildconsent') try: caregiver_child_consent_obj = caregiver_child_consent_cls.objects.get( subject_identifier=instance.subject_identifier, subject_consent__version=instance.version) except caregiver_child_consent_cls.DoesNotExist: raise CaregiverConsentError( 'Associated caregiver consent on behalf of ' 'child for this participant not found') else: if caregiver_child_consent_obj.is_eligible: try: dummy_consent_obj = ChildDummySubjectConsent.objects.get( subject_identifier=instance.subject_identifier) except ChildDummySubjectConsent.DoesNotExist: ChildDummySubjectConsent.objects.create( subject_identifier=instance.subject_identifier, consent_datetime=instance.consent_datetime, identity=instance.identity, dob=instance.dob, cohort=caregiver_child_consent_obj.cohort, version=instance.version) else: caregiver_prev_enrolled_cls = django_apps.get_model( 'flourish_caregiver.caregiverpreviouslyenrolled') try: caregiver_prev_enrolled_cls.objects.get( subject_identifier=instance. subject_identifier[:-3]) except caregiver_prev_enrolled_cls.DoesNotExist: pass else: dummy_consent_obj.save() caregiver_child_consent_obj.subject_identifier = instance.subject_identifier caregiver_child_consent_obj.save(update_fields=[ 'subject_identifier', 'modified', 'user_modified' ])
def hiv_disclosed_or_offstudy(self): child_age = ChildBirthValues( subject_identifier=self.subject_identifier).child_age child_offstudy_cls = django_apps.get_model( 'flourish_prn.childoffstudy') child_visit_cls = django_apps.get_model('flourish_child.childvisit') try: child_registered_subject = RegisteredSubject.objects.get( subject_identifier=self.subject_identifier) except RegisteredSubject.DoesNotExist: raise ValidationError( "Registered subject for the mother is expected to exist.") else: reg_age = age(child_registered_subject.dob, child_registered_subject.consent_datetime) child_age = float(f'{reg_age.years}.{reg_age.months}') if self.maternal_hiv_status == POS and child_age and child_age >= 16: for disclosure_cls in [ 'hivdisclosurestatusa', 'hivdisclosurestatusb', 'hivdisclosurestatusc' ]: hiv_disclosure_cls = django_apps.get_model( f'flourish_caregiver.{disclosure_cls}') try: hiv_disclosure_cls.objects.get( associated_child_identifier=self.subject_identifier, disclosed_status=YES) except hiv_disclosure_cls.DoesNotExist: trigger = True else: trigger = False break self.get_offstudy_or_message(visit_cls=child_visit_cls, offstudy_cls=child_offstudy_cls, offstudy_action=CHILDOFF_STUDY_ACTION, trigger=trigger)
def validate_child_knows_status(self, cleaned_data): child_dob = cleaned_data.get('child_dob') if child_dob: child_dob = datetime.datetime.strptime(child_dob, "%Y-%m-%d").date() child_age = age(child_dob, get_utcnow()).years if child_age < 16 and cleaned_data.get('child_knows_status') in [ YES, NO ]: msg = {'child_knows_status': 'Child is less than 16 years'} self._errors.update(msg) raise ValidationError(msg) elif child_age >= 16 and cleaned_data.get( 'child_knows_status') == NOT_APPLICABLE: msg = {'child_knows_status': 'This field is applicable'} self._errors.update(msg) raise ValidationError(msg)
def validate_hpv_vaccine(self, cleaned_data): received_vaccine_name = cleaned_data.get('received_vaccine_name') if self.caregiver_child_consent_model: child_dob = self.caregiver_child_consent_model.child_dob child_age = age(child_dob, get_utcnow().date()).years if child_age <= 12 and received_vaccine_name == 'hpv_vaccine': message = {'received_vaccine_name': 'Child age is less than 12, cannot select HPV vaccine'} self._errors.update(message) raise ValidationError(message) if cleaned_data.get('child_age') == 'adolescent': if received_vaccine_name != 'hpv_vaccine': msg = {'child_age': 'Cannot select Adolescent if vaccine is not HPV.'} self._errors.update(msg) raise ValidationError(msg) if (received_vaccine_name == 'hpv_vaccine' and not cleaned_data.get('child_age') == 'adolescent'): msg = {'child_age': 'HPV vaccine selected, child age should be adolescent.'} self._errors.update(msg) raise ValidationError(msg)
def update_dob(self, enrollment_checklist): if self.new_dob: if enrollment_checklist: enrollment_checklist.dob = self.new_dob enrollment_checklist.save( update_fields=['dob', 'age_in_years', 'user_modified']) household_member = HouseholdMember.objects.filter( subject_identifier=self.subject_consent.subject_identifier) for member in household_member: try: member.age_in_years = age(self.new_dob, member.report_datetime) member.save( update_fields=['age_in_years', 'user_modified']) except: pass self.subject_consent.dob = self.new_dob self.subject_consent.save(update_fields=['dob', 'user_modified']) subject_consents = SubjectConsent.objects.filter( subject_identifier=self.subject_consent.subject_identifier) for consent in subject_consents: try: consent.dob = self.new_dob consent.save(update_fields=['dob', 'user_modified']) except: pass try: hic_enrollment = HicEnrollment.objects.get( subject_visit__household_member=self.subject_consent. household_member) hic_enrollment.dob = self.new_dob hic_enrollment.user_modified = self.update_user_modified() hic_enrollment.save(update_fields=['dob', 'user_modified']) except HicEnrollment.DoesNotExist: pass return enrollment_checklist
def clone(self, household_structure, report_datetime, **kwargs): """Returns a new unsaved household member instance. * household_structure: the 'next' household_structure to which the new members will be related. """ with transaction.atomic(): try: self.__class__.objects.get( internal_identifier=self.internal_identifier, household_structure=household_structure) except self.__class__.DoesNotExist: pass else: raise CloneMembersExistError( 'Cannot clone a household member into a survey ' 'where the member already exists') with transaction.atomic(): try: registered_subject = RegisteredSubject.objects.get( registration_identifier=self.internal_identifier.hex) except RegisteredSubject.DoesNotExist: raise CloneRegisteredSubjectError( 'RegisteredSubject instance unexpectedly missing when ' 'cloning member! Got internal identifier = {}.'.format( self.internal_identifier)) else: if not registered_subject.dob: born = (self.report_datetime - relativedelta(years=self.age_in_years)) age_in_years = age(born, report_datetime).years else: age_in_years = age(registered_subject.dob, report_datetime).years start = household_structure.survey_schedule_object.rstart end = household_structure.survey_schedule_object.rend rdate = arrow.Arrow.fromdatetime(report_datetime, report_datetime.tzinfo) if not (start.to('utc').date() <= rdate.to('utc').date() <= end.to('utc').date()): raise CloneReportDatetimeError( 'Invalid report datetime. \'{}\' does not fall within ' 'the date range for survey schedule \'{}\'. Expected any date ' 'from \'{}\' to \'{}\'.'.format( report_datetime.strftime('%Y-%m-%d %Z'), household_structure.survey_schedule_object.field_value, start.to('utc').strftime('%Y-%m-%d %Z'), end.to('utc').strftime('%Y-%m-%d %Z'))) return self.__class__( household_structure=household_structure, report_datetime=report_datetime, first_name=self.first_name, initials=self.initials, gender=self.gender, survival_status=ALIVE if not self.survival_status else self.survival_status, age_in_years=age_in_years, relation=None if self.relation == HEAD_OF_HOUSEHOLD else self.relation, internal_identifier=self.internal_identifier, subject_identifier=self.subject_identifier, subject_identifier_as_pk=self.subject_identifier_as_pk, cloned=True, cloned_datetime=get_utcnow(), personal_details_changed=None, survey_schedule=household_structure.survey_schedule, user_created=kwargs.get('user_created', self.user_created), )
def age_at_consent(self): """Returns a relativedelta. """ return age(self.dob, self.consent_datetime)
def is_minor(dob, reference_datetime): return 16 <= age(dob, reference_datetime).years < 18
def age_at_consent(self): """Returns a relativedelta. """ if self.dob < self.consent_datetime.date(): return age(self.dob, self.consent_datetime) return 0
def caregiver_child_consent_on_post_save(sender, instance, raw, created, **kwargs): """ - Put subject on cohort a schedule after consenting on behalf of child. """ if not raw and instance.is_eligible: child_dummy_consent_cls = django_apps.get_model( 'flourish_child.childdummysubjectconsent') child_age = None children_count = instance.caregiver_visit_count if not children_count: children_count = 1 + child_dummy_consent_cls.objects.filter( subject_identifier__startswith=instance.subject_consent. subject_identifier).exclude(dob=instance.child_dob, ).count() if instance.child_dob: child_age = age(instance.child_dob, get_utcnow()) if not instance.cohort: cohort = cohort_assigned(instance.study_child_identifier, instance.child_dob, instance.subject_consent.created.date()) if not cohort and screening_preg_exists(instance): cohort = 'cohort_a' if child_age is not None and child_age.years < 7: try: child_dummy_consent_cls.objects.get( identity=instance.identity, subject_identifier=instance.subject_identifier, version=instance.subject_consent.version, ) except child_dummy_consent_cls.DoesNotExist: child_dummy_consent_cls.objects.create( subject_identifier=instance.subject_identifier, consent_datetime=instance.consent_datetime, identity=instance.identity, dob=instance.child_dob, version=instance.subject_consent.version, cohort=cohort) instance.cohort = cohort instance.save_base(raw=True) if created: instance.caregiver_visit_count = children_count else: try: prev_enrolled_obj = CaregiverPreviouslyEnrolled.objects.get( subject_identifier=instance.subject_consent. subject_identifier) except CaregiverPreviouslyEnrolled.DoesNotExist: pass else: if child_age: if instance.subject_identifier[-3:] not in [ '-35', '-46', '-56' ]: put_cohort_onschedule( instance.cohort, instance, base_appt_datetime=prev_enrolled_obj. report_datetime.replace(microsecond=0)) try: child_dummy_consent = child_dummy_consent_cls.objects.get( subject_identifier=instance.subject_identifier, version=instance.subject_consent.version, identity=instance.identity) except child_dummy_consent_cls.DoesNotExist: pass else: if not child_dummy_consent.cohort: child_dummy_consent.cohort = instance.cohort child_dummy_consent.save() if instance.study_child_identifier: update_maternal_dataset_and_worklist( instance.subject_consent.subject_identifier, study_child_identifier=instance.study_child_identifier)
def age_in_years(self): return age(self.subject_consent.dob, get_utcnow()).years