From 24d99defacd8dd97f0c9302cf2a126f49a47ac1e Mon Sep 17 00:00:00 2001 From: CoprDistGit Date: Fri, 9 Jun 2023 00:18:54 +0000 Subject: automatic import of python-edc-visit-tracking --- .gitignore | 1 + python-edc-visit-tracking.spec | 432 +++++++++++++++++++++++++++++++++++++++++ sources | 1 + 3 files changed, 434 insertions(+) create mode 100644 python-edc-visit-tracking.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore index e69de29..4691ec0 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/edc-visit-tracking-0.3.52.tar.gz diff --git a/python-edc-visit-tracking.spec b/python-edc-visit-tracking.spec new file mode 100644 index 0000000..3c88253 --- /dev/null +++ b/python-edc-visit-tracking.spec @@ -0,0 +1,432 @@ +%global _empty_manifest_terminate_build 0 +Name: python-edc-visit-tracking +Version: 0.3.52 +Release: 1 +Summary: Base classes for visit reports/tracking in clinicedc/edc +License: GPL license, see LICENSE +URL: https://github.com/clinicedc/edc-visit-tracking +Source0: https://mirrors.aliyun.com/pypi/web/packages/df/55/14fac39c639c9d0b852875a130a6b511fea3ac221b252f555c0bcd9c29ec/edc-visit-tracking-0.3.52.tar.gz +BuildArch: noarch + + +%description +Track study participant visit reports. +Declaring a visit model ++++++++++++++++++++++++ +A **visit_model** is declared using the model mixin `VisitModelMixin`. Normally, a **visit_model** will be declared with additional model mixins, but `VisitModelMixin` must be there. + class SubjectVisit(VisitModelMixin, BaseUuidModel): +Also, ensure the `Meta` class attributes of `VisitModelMixin` are inherited. These include required constraints and ordering. + class SubjectVisit(VisitModelMixin, BaseUuidModel): + class Meta(VisitModelMixin.Meta): + pass +Among other features, `VisitModelMixin` adds a `OneToOneField` foreign key to the **visit_model** that points to `edc_appointment.Appointment`. + Important: A **visit model** is a special model in the EDC. A model declared with the model mixin, `VisitModelMixin`, is the definition of a **visit model**. CRFs and Requisitions have a foreign key pointing to a **visit model**. A number of methods on CRFs and Requisitions detect their **visit model** foreign key name, model class and value by looking for the FK declared with `VisitModelMixin`. +For a subject that requires ICF the **visit model** would use the `RequiresConsentModelMixin`: + class SubjectVisit( + VisitModelMixin, + RequiresConsentFieldsModelMixin, + BaseUuidModel, + ): + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +If the subject does not require ICF, such as an infant, don't include the `RequiresConsentModelMixin`: + class InfantVisit( + VisitModelMixin, + BaseUuidModel + ): + class Meta(VisitModelMixin.Meta, , BaseUuidModel.Meta): + pass +A more complete declaration will include model mixins from other libraries. For example: + from edc_consent.model_mixins import RequiresConsentFieldsModelMixin + from edc_metadata.model_mixins.creates import CreatesMetadataModelMixin + from edc_model.models import BaseUuidModel + from edc_offstudy.model_mixins import OffstudyVisitModelMixin + from edc_reference.model_mixins import ReferenceModelMixin + from edc_sites.models import CurrentSiteManager + from edc_sites.models import SiteModelMixin + from edc_visit_tracking.managers import VisitModelManager + from edc_visit_tracking.model_mixins import VisitModelMixin + class SubjectVisit( + SiteModelMixin, + VisitModelMixin, + ReferenceModelMixin, + CreatesMetadataModelMixin, + RequiresConsentFieldsModelMixin, + OffstudyNonCrfModelMixin, + BaseUuidModel, + ): + on_site = CurrentSiteManager() + objects = VisitModelManager() + history = edc_models.HistoricalRecords() + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +Declaring a CRF ++++++++++++++++ +The `CrfModelMixin` is required for all CRF models. CRF models have a `OneToOneField` key to a **visit model**. + class CrfOne(CrfModelMixin, OffstudyCrfModelMixin, RequiresConsentModelMixin, + UpdatesCrfMetadataModelMixin, BaseUuidModel): + subject_visit = models.OneToOneField(SubjectVisit) + f1 = models.CharField(max_length=10, default='erik') + vl = models.CharField(max_length=10, default=NO) + rdb = models.CharField(max_length=10, default=NO) + class Meta: + consent_model = 'myapp.subjectconsent' # for RequiresConsentModelMixin +Declaring forms: +++++++++++++++++ +The `VisitFormMixin` includes a number of common validations in the `clean` method: + class SubjectVisitForm(VisitFormMixin, FormValidatorMixin, forms.ModelForm): + form_validator_cls = VisitFormValidator + class Meta: + model = SubjectVisit +`PreviousVisitModelMixin` ++++++++++++++++++++++++++ +The `PreviousVisitModelMixin` ensures that visits are entered in sequence. It is included with the `VisitModelMixin`. +`VisitTrackingModelFormMixin` ++++++++++++++++++++++++++++++ + see `DEFAULT_REPORT_DATETIME_ALLOWANCE` +Missed Visit Report ++++++++++++++++++++ +A detail report should be submitted for scheduled visits that are missed. +By selecting the reason ``missed visit`` on ``SubjectVisit``, only the missed visit CRF will be required +for the timepoint. All other CRFs and requisitions will be excluded. +Unscheduled visits cannot be missed. (To change this behaviour see `settings` attrubute `EDC_VISIT_TRACKING_ALLOW_MISSED_UNSCHEDULED`) +The model mixin ``SubjectVisitMissedModelMixin`` provides the basic features of a `SubjectVisitMissed` model. +In your subject app declare: + from django.db.models import PROTECT + from edc_crf.model_mixins import CrfWithActionModelMixin + from edc_model import models as edc_models + from edc_visit_tracking.model_mixins import SubjectVisitMissedModelMixin + class SubjectVisitMissed(SubjectVisitMissedModelMixin, edc_models.BaseUuidModel): + missed_reasons = models.ManyToManyField( + SubjectVisitMissedReasons, blank=True, related_name="+" + ) + class Meta(CrfWithActionModelMixin.Meta, edc_models.BaseUuidModel.Meta): + verbose_name = "Missed Visit Report" + verbose_name_plural = "Missed Visit Report" +In your list model app, e.g. ``meta_lists``, declare the list model: + class SubjectVisitMissedReasons(ListModelMixin): + class Meta(ListModelMixin.Meta): + verbose_name = "Subject Missed Visit Reasons" + verbose_name_plural = "Subject Missed Visit Reasons" + list_data = { + "meta_lists.subjectvisitmissedreasons": [ + ("forgot", "Forgot / Can’t remember being told about appointment"), + ("family_emergency", "Family emergency (e.g. funeral) and was away"), + ("travelling", "Away travelling/visiting"), + ("working_schooling", "Away working/schooling"), + ("too_sick", "Too sick or weak to come to the centre"), + ("lack_of_transport", "Transportation difficulty"), + (OTHER, "Other reason (specify below)",), + ], + } +Window period ++++++++++++++ +By default, the visit `report_datetime` is validated to stay within the same window period as the appointment. +This may be too restrictive in some cases. +To bypass this override ```validate_visit_datetime_in_window_period``` in the ```VisitFormValidator``` + from edc_visit_tracking.form_validators import VisitFormValidator as BaseVisitFormValidator + class VisitFormValidator(BaseVisitFormValidator): + def validate_visit_datetime_in_window_period(): + pass +Be sure that your appointment form validator is enforcing window periods before +bypassing this check. +See also `edc_appointment`. + +%package -n python3-edc-visit-tracking +Summary: Base classes for visit reports/tracking in clinicedc/edc +Provides: python-edc-visit-tracking +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-edc-visit-tracking +Track study participant visit reports. +Declaring a visit model ++++++++++++++++++++++++ +A **visit_model** is declared using the model mixin `VisitModelMixin`. Normally, a **visit_model** will be declared with additional model mixins, but `VisitModelMixin` must be there. + class SubjectVisit(VisitModelMixin, BaseUuidModel): +Also, ensure the `Meta` class attributes of `VisitModelMixin` are inherited. These include required constraints and ordering. + class SubjectVisit(VisitModelMixin, BaseUuidModel): + class Meta(VisitModelMixin.Meta): + pass +Among other features, `VisitModelMixin` adds a `OneToOneField` foreign key to the **visit_model** that points to `edc_appointment.Appointment`. + Important: A **visit model** is a special model in the EDC. A model declared with the model mixin, `VisitModelMixin`, is the definition of a **visit model**. CRFs and Requisitions have a foreign key pointing to a **visit model**. A number of methods on CRFs and Requisitions detect their **visit model** foreign key name, model class and value by looking for the FK declared with `VisitModelMixin`. +For a subject that requires ICF the **visit model** would use the `RequiresConsentModelMixin`: + class SubjectVisit( + VisitModelMixin, + RequiresConsentFieldsModelMixin, + BaseUuidModel, + ): + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +If the subject does not require ICF, such as an infant, don't include the `RequiresConsentModelMixin`: + class InfantVisit( + VisitModelMixin, + BaseUuidModel + ): + class Meta(VisitModelMixin.Meta, , BaseUuidModel.Meta): + pass +A more complete declaration will include model mixins from other libraries. For example: + from edc_consent.model_mixins import RequiresConsentFieldsModelMixin + from edc_metadata.model_mixins.creates import CreatesMetadataModelMixin + from edc_model.models import BaseUuidModel + from edc_offstudy.model_mixins import OffstudyVisitModelMixin + from edc_reference.model_mixins import ReferenceModelMixin + from edc_sites.models import CurrentSiteManager + from edc_sites.models import SiteModelMixin + from edc_visit_tracking.managers import VisitModelManager + from edc_visit_tracking.model_mixins import VisitModelMixin + class SubjectVisit( + SiteModelMixin, + VisitModelMixin, + ReferenceModelMixin, + CreatesMetadataModelMixin, + RequiresConsentFieldsModelMixin, + OffstudyNonCrfModelMixin, + BaseUuidModel, + ): + on_site = CurrentSiteManager() + objects = VisitModelManager() + history = edc_models.HistoricalRecords() + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +Declaring a CRF ++++++++++++++++ +The `CrfModelMixin` is required for all CRF models. CRF models have a `OneToOneField` key to a **visit model**. + class CrfOne(CrfModelMixin, OffstudyCrfModelMixin, RequiresConsentModelMixin, + UpdatesCrfMetadataModelMixin, BaseUuidModel): + subject_visit = models.OneToOneField(SubjectVisit) + f1 = models.CharField(max_length=10, default='erik') + vl = models.CharField(max_length=10, default=NO) + rdb = models.CharField(max_length=10, default=NO) + class Meta: + consent_model = 'myapp.subjectconsent' # for RequiresConsentModelMixin +Declaring forms: +++++++++++++++++ +The `VisitFormMixin` includes a number of common validations in the `clean` method: + class SubjectVisitForm(VisitFormMixin, FormValidatorMixin, forms.ModelForm): + form_validator_cls = VisitFormValidator + class Meta: + model = SubjectVisit +`PreviousVisitModelMixin` ++++++++++++++++++++++++++ +The `PreviousVisitModelMixin` ensures that visits are entered in sequence. It is included with the `VisitModelMixin`. +`VisitTrackingModelFormMixin` ++++++++++++++++++++++++++++++ + see `DEFAULT_REPORT_DATETIME_ALLOWANCE` +Missed Visit Report ++++++++++++++++++++ +A detail report should be submitted for scheduled visits that are missed. +By selecting the reason ``missed visit`` on ``SubjectVisit``, only the missed visit CRF will be required +for the timepoint. All other CRFs and requisitions will be excluded. +Unscheduled visits cannot be missed. (To change this behaviour see `settings` attrubute `EDC_VISIT_TRACKING_ALLOW_MISSED_UNSCHEDULED`) +The model mixin ``SubjectVisitMissedModelMixin`` provides the basic features of a `SubjectVisitMissed` model. +In your subject app declare: + from django.db.models import PROTECT + from edc_crf.model_mixins import CrfWithActionModelMixin + from edc_model import models as edc_models + from edc_visit_tracking.model_mixins import SubjectVisitMissedModelMixin + class SubjectVisitMissed(SubjectVisitMissedModelMixin, edc_models.BaseUuidModel): + missed_reasons = models.ManyToManyField( + SubjectVisitMissedReasons, blank=True, related_name="+" + ) + class Meta(CrfWithActionModelMixin.Meta, edc_models.BaseUuidModel.Meta): + verbose_name = "Missed Visit Report" + verbose_name_plural = "Missed Visit Report" +In your list model app, e.g. ``meta_lists``, declare the list model: + class SubjectVisitMissedReasons(ListModelMixin): + class Meta(ListModelMixin.Meta): + verbose_name = "Subject Missed Visit Reasons" + verbose_name_plural = "Subject Missed Visit Reasons" + list_data = { + "meta_lists.subjectvisitmissedreasons": [ + ("forgot", "Forgot / Can’t remember being told about appointment"), + ("family_emergency", "Family emergency (e.g. funeral) and was away"), + ("travelling", "Away travelling/visiting"), + ("working_schooling", "Away working/schooling"), + ("too_sick", "Too sick or weak to come to the centre"), + ("lack_of_transport", "Transportation difficulty"), + (OTHER, "Other reason (specify below)",), + ], + } +Window period ++++++++++++++ +By default, the visit `report_datetime` is validated to stay within the same window period as the appointment. +This may be too restrictive in some cases. +To bypass this override ```validate_visit_datetime_in_window_period``` in the ```VisitFormValidator``` + from edc_visit_tracking.form_validators import VisitFormValidator as BaseVisitFormValidator + class VisitFormValidator(BaseVisitFormValidator): + def validate_visit_datetime_in_window_period(): + pass +Be sure that your appointment form validator is enforcing window periods before +bypassing this check. +See also `edc_appointment`. + +%package help +Summary: Development documents and examples for edc-visit-tracking +Provides: python3-edc-visit-tracking-doc +%description help +Track study participant visit reports. +Declaring a visit model ++++++++++++++++++++++++ +A **visit_model** is declared using the model mixin `VisitModelMixin`. Normally, a **visit_model** will be declared with additional model mixins, but `VisitModelMixin` must be there. + class SubjectVisit(VisitModelMixin, BaseUuidModel): +Also, ensure the `Meta` class attributes of `VisitModelMixin` are inherited. These include required constraints and ordering. + class SubjectVisit(VisitModelMixin, BaseUuidModel): + class Meta(VisitModelMixin.Meta): + pass +Among other features, `VisitModelMixin` adds a `OneToOneField` foreign key to the **visit_model** that points to `edc_appointment.Appointment`. + Important: A **visit model** is a special model in the EDC. A model declared with the model mixin, `VisitModelMixin`, is the definition of a **visit model**. CRFs and Requisitions have a foreign key pointing to a **visit model**. A number of methods on CRFs and Requisitions detect their **visit model** foreign key name, model class and value by looking for the FK declared with `VisitModelMixin`. +For a subject that requires ICF the **visit model** would use the `RequiresConsentModelMixin`: + class SubjectVisit( + VisitModelMixin, + RequiresConsentFieldsModelMixin, + BaseUuidModel, + ): + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +If the subject does not require ICF, such as an infant, don't include the `RequiresConsentModelMixin`: + class InfantVisit( + VisitModelMixin, + BaseUuidModel + ): + class Meta(VisitModelMixin.Meta, , BaseUuidModel.Meta): + pass +A more complete declaration will include model mixins from other libraries. For example: + from edc_consent.model_mixins import RequiresConsentFieldsModelMixin + from edc_metadata.model_mixins.creates import CreatesMetadataModelMixin + from edc_model.models import BaseUuidModel + from edc_offstudy.model_mixins import OffstudyVisitModelMixin + from edc_reference.model_mixins import ReferenceModelMixin + from edc_sites.models import CurrentSiteManager + from edc_sites.models import SiteModelMixin + from edc_visit_tracking.managers import VisitModelManager + from edc_visit_tracking.model_mixins import VisitModelMixin + class SubjectVisit( + SiteModelMixin, + VisitModelMixin, + ReferenceModelMixin, + CreatesMetadataModelMixin, + RequiresConsentFieldsModelMixin, + OffstudyNonCrfModelMixin, + BaseUuidModel, + ): + on_site = CurrentSiteManager() + objects = VisitModelManager() + history = edc_models.HistoricalRecords() + class Meta(VisitModelMixin.Meta, BaseUuidModel.Meta): + pass +Declaring a CRF ++++++++++++++++ +The `CrfModelMixin` is required for all CRF models. CRF models have a `OneToOneField` key to a **visit model**. + class CrfOne(CrfModelMixin, OffstudyCrfModelMixin, RequiresConsentModelMixin, + UpdatesCrfMetadataModelMixin, BaseUuidModel): + subject_visit = models.OneToOneField(SubjectVisit) + f1 = models.CharField(max_length=10, default='erik') + vl = models.CharField(max_length=10, default=NO) + rdb = models.CharField(max_length=10, default=NO) + class Meta: + consent_model = 'myapp.subjectconsent' # for RequiresConsentModelMixin +Declaring forms: +++++++++++++++++ +The `VisitFormMixin` includes a number of common validations in the `clean` method: + class SubjectVisitForm(VisitFormMixin, FormValidatorMixin, forms.ModelForm): + form_validator_cls = VisitFormValidator + class Meta: + model = SubjectVisit +`PreviousVisitModelMixin` ++++++++++++++++++++++++++ +The `PreviousVisitModelMixin` ensures that visits are entered in sequence. It is included with the `VisitModelMixin`. +`VisitTrackingModelFormMixin` ++++++++++++++++++++++++++++++ + see `DEFAULT_REPORT_DATETIME_ALLOWANCE` +Missed Visit Report ++++++++++++++++++++ +A detail report should be submitted for scheduled visits that are missed. +By selecting the reason ``missed visit`` on ``SubjectVisit``, only the missed visit CRF will be required +for the timepoint. All other CRFs and requisitions will be excluded. +Unscheduled visits cannot be missed. (To change this behaviour see `settings` attrubute `EDC_VISIT_TRACKING_ALLOW_MISSED_UNSCHEDULED`) +The model mixin ``SubjectVisitMissedModelMixin`` provides the basic features of a `SubjectVisitMissed` model. +In your subject app declare: + from django.db.models import PROTECT + from edc_crf.model_mixins import CrfWithActionModelMixin + from edc_model import models as edc_models + from edc_visit_tracking.model_mixins import SubjectVisitMissedModelMixin + class SubjectVisitMissed(SubjectVisitMissedModelMixin, edc_models.BaseUuidModel): + missed_reasons = models.ManyToManyField( + SubjectVisitMissedReasons, blank=True, related_name="+" + ) + class Meta(CrfWithActionModelMixin.Meta, edc_models.BaseUuidModel.Meta): + verbose_name = "Missed Visit Report" + verbose_name_plural = "Missed Visit Report" +In your list model app, e.g. ``meta_lists``, declare the list model: + class SubjectVisitMissedReasons(ListModelMixin): + class Meta(ListModelMixin.Meta): + verbose_name = "Subject Missed Visit Reasons" + verbose_name_plural = "Subject Missed Visit Reasons" + list_data = { + "meta_lists.subjectvisitmissedreasons": [ + ("forgot", "Forgot / Can’t remember being told about appointment"), + ("family_emergency", "Family emergency (e.g. funeral) and was away"), + ("travelling", "Away travelling/visiting"), + ("working_schooling", "Away working/schooling"), + ("too_sick", "Too sick or weak to come to the centre"), + ("lack_of_transport", "Transportation difficulty"), + (OTHER, "Other reason (specify below)",), + ], + } +Window period ++++++++++++++ +By default, the visit `report_datetime` is validated to stay within the same window period as the appointment. +This may be too restrictive in some cases. +To bypass this override ```validate_visit_datetime_in_window_period``` in the ```VisitFormValidator``` + from edc_visit_tracking.form_validators import VisitFormValidator as BaseVisitFormValidator + class VisitFormValidator(BaseVisitFormValidator): + def validate_visit_datetime_in_window_period(): + pass +Be sure that your appointment form validator is enforcing window periods before +bypassing this check. +See also `edc_appointment`. + +%prep +%autosetup -n edc-visit-tracking-0.3.52 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-edc-visit-tracking -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri Jun 09 2023 Python_Bot - 0.3.52-1 +- Package Spec generated diff --git a/sources b/sources new file mode 100644 index 0000000..8ee6f73 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +46a09f1910800d6380966a5841b34f14 edc-visit-tracking-0.3.52.tar.gz -- cgit v1.2.3