clinicedc 2.0.4__py3-none-any.whl → 2.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of clinicedc might be problematic. Click here for more details.
- {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/METADATA +41 -45
- {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/RECORD +478 -478
- edc_action_item/action.py +76 -54
- edc_action_item/action_item_notification.py +1 -3
- edc_action_item/action_with_notification.py +4 -4
- edc_action_item/create_action_item.py +2 -2
- edc_action_item/create_or_update_action_type.py +1 -1
- edc_action_item/data_fixers.py +4 -5
- edc_action_item/delete_action_item.py +0 -1
- edc_action_item/modeladmin_mixins.py +2 -4
- edc_action_item/modelform_mixins/modelform_mixins.py +1 -1
- edc_action_item/models/action_item.py +53 -38
- edc_action_item/models/action_model_mixin.py +17 -17
- edc_action_item/models/action_type.py +33 -13
- edc_action_item/models/reference.py +3 -2
- edc_action_item/site_action_items.py +13 -14
- edc_action_item/stubs.py +9 -9
- edc_action_item/templatetags/action_item_extras.py +2 -2
- edc_action_item/view_utils/action_item_button.py +3 -3
- edc_action_item/view_utils/action_item_popover_list_item.py +4 -4
- edc_adherence/form_validator_mixin.py +1 -1
- edc_adverse_event/action_items/ae_followup_action.py +1 -1
- edc_adverse_event/action_items/ae_initial_action.py +1 -1
- edc_adverse_event/action_items/ae_susar_action.py +1 -1
- edc_adverse_event/action_items/ae_tmg_action.py +1 -1
- edc_adverse_event/action_items/death_report_action.py +1 -2
- edc_adverse_event/action_items/death_report_tmg_action.py +1 -1
- edc_adverse_event/action_items/death_report_tmg_second_action.py +1 -1
- edc_adverse_event/action_items/hospitalization_action.py +1 -1
- edc_adverse_event/form_validator_mixins/death_report_form_validator.py +3 -3
- edc_adverse_event/form_validator_mixins/requires_death_report_form_validator_mixin.py +3 -4
- edc_adverse_event/form_validators/death_report_tmg.py +1 -1
- edc_adverse_event/model_mixins/ae_followup/ae_followup_methods_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_followup/ae_followup_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +0 -1
- edc_adverse_event/model_mixins/ae_initial/ae_initial_methods_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_initial/ae_initial_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_special_interest/aesi_methods_model_mixin.py +4 -4
- edc_adverse_event/model_mixins/ae_special_interest/aesi_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_susar/ae_susar_methods_model_mixin.py +4 -4
- edc_adverse_event/model_mixins/ae_susar/ae_susar_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +4 -5
- edc_adverse_event/model_mixins/ae_tmg/ae_tmg_methods_model_mixin.py +4 -4
- edc_adverse_event/model_mixins/ae_tmg/ae_tmg_model_mixin.py +3 -3
- edc_adverse_event/model_mixins/death_report/death_report_extra_fields_model_mixin.py +2 -3
- edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +11 -11
- edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +9 -11
- edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +7 -6
- edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +0 -1
- edc_adverse_event/modeladmin_mixins/ae_followup_admin_mixin.py +9 -11
- edc_adverse_event/modeladmin_mixins/ae_initial_admin_mixin.py +4 -6
- edc_adverse_event/modeladmin_mixins/modeladmin_mixins.py +1 -1
- edc_adverse_event/modeladmin_mixins/utils.py +4 -4
- edc_adverse_event/models/signals.py +7 -19
- edc_adverse_event/pdf_reports/death_pdf_report.py +8 -9
- edc_adverse_event/templatetags/edc_adverse_event_extras.py +10 -20
- edc_adverse_event/urls.py +7 -3
- edc_adverse_event/utils.py +2 -2
- edc_adverse_event/view_utils/tmg_button.py +4 -4
- edc_appconfig/system_checks.py +1 -1
- edc_appointment/appointment_status_updater.py +14 -15
- edc_appointment/creators/appointment_creator.py +7 -11
- edc_appointment/creators/appointments_creator.py +1 -1
- edc_appointment/creators/unscheduled_appointment_creator.py +12 -13
- edc_appointment/form_validator_mixins/next_appointment_crf_form_validator_mixin.py +1 -3
- edc_appointment/form_validator_mixins/window_period_form_validator_mixin.py +7 -6
- edc_appointment/form_validators/appointment_form_validator.py +2 -4
- edc_appointment/form_validators/utils.py +4 -4
- edc_appointment/managers.py +4 -4
- edc_appointment/model_mixins/appointment_methods_model_mixin.py +2 -2
- edc_appointment/model_mixins/appointment_model_mixin.py +5 -5
- edc_appointment/model_mixins/window_period_model_mixin.py +1 -1
- edc_appointment/models/appointment.py +1 -1
- edc_appointment/skip_appointments.py +5 -6
- edc_appointment/stubs.py +12 -12
- edc_appointment/utils.py +41 -47
- edc_appointment/view_utils/appointment_button.py +3 -5
- edc_auth/admin/role_admin.py +5 -7
- edc_auth/auth_objects/default_roles.py +1 -3
- edc_auth/auth_updater/auth_updater.py +5 -7
- edc_auth/auth_updater/group_updater.py +8 -8
- edc_auth/auth_updater/role_updater.py +1 -2
- edc_auth/get_app_codenames.py +1 -3
- edc_auth/import_users.py +19 -19
- edc_auth/models/role.py +4 -3
- edc_auth/password_setter.py +6 -7
- edc_auth/send_new_credentials_to_user.py +2 -3
- edc_auth/site_auths.py +3 -3
- edc_consent/actions.py +4 -5
- edc_consent/consent_definition.py +8 -11
- edc_consent/consent_definition_extension.py +3 -3
- edc_consent/form_validators/__init__.py +1 -1
- edc_consent/model_mixins/__init__.py +2 -2
- edc_consent/model_mixins/consent_version_model_mixin.py +1 -1
- edc_consent/modeladmin_mixins/consent_model_admin_mixin.py +1 -2
- edc_consent/modelform_mixins/consent_modelform_mixin/consent_modelform_validation_mixin.py +3 -5
- edc_consent/site_consents.py +10 -15
- edc_consent/stubs.py +2 -2
- edc_consent/utils.py +1 -1
- edc_constants/utils.py +2 -4
- edc_crf/crf_form_validator_mixins.py +2 -2
- edc_crf/model_mixins/crf_no_manager_model_mixin.py +2 -2
- edc_crf/model_mixins/crf_status_model_mixin.py +1 -1
- edc_crf/models/crf_status.py +10 -12
- edc_crf/update_crf_status_command.py +1 -3
- edc_dashboard/management/commands/update_search_slugs.py +8 -11
- edc_dashboard/templatetags/edc_dashboard_extras.py +1 -1
- edc_dashboard/url_config.py +3 -3
- edc_dashboard/utils.py +3 -4
- edc_dashboard/views/dashboard_view.py +1 -1
- edc_data_manager/models/data_dictionary.py +1 -2
- edc_data_manager/models/data_query.py +3 -3
- edc_data_manager/models/query_rule.py +2 -2
- edc_data_manager/tasks.py +0 -2
- edc_device/device.py +1 -1
- edc_device/view_mixins.py +1 -1
- edc_document_status/fieldsets.py +1 -3
- edc_document_status/model_mixins.py +2 -2
- edc_document_status/modeladmin_mixins.py +1 -4
- edc_egfr/admin/egfr_drop_notification_admin_mixin.py +5 -7
- edc_egfr/egfr.py +6 -7
- edc_egfr/get_drop_notification_model.py +1 -1
- edc_egfr/model_mixins/egfr_drop_notification_model_mixin.py +1 -1
- edc_export/archive_exporter.py +26 -27
- edc_export/exportables.py +2 -3
- edc_export/management/commands/import_receipts.py +6 -6
- edc_export/model_exporter/file_history_updater.py +1 -1
- edc_export/model_exporter/model_exporter.py +1 -1
- edc_export/model_exporter/value_getter.py +6 -6
- edc_export/model_mixins/notification_model_mixin.py +4 -4
- edc_export/models/data_request.py +3 -3
- edc_export/models/data_request_history.py +2 -2
- edc_export/models/export_receipt.py +1 -1
- edc_export/models/file_history.py +5 -5
- edc_export/models/plan.py +4 -4
- edc_export/models/upload_export_receipt_file.py +2 -2
- edc_export/utils.py +1 -1
- edc_facility/facility.py +6 -6
- edc_facility/holidays.py +2 -5
- edc_facility/import_holidays.py +6 -6
- edc_facility/model_mixins.py +1 -1
- edc_facility/models/holiday.py +1 -1
- edc_facility/utils.py +3 -3
- edc_fieldsets/fieldsets.py +1 -1
- edc_form_describer/forms_reference.py +5 -8
- edc_form_describer/make_forms_reference.py +1 -1
- edc_form_describer/management/commands/make_forms_reference.py +1 -1
- edc_form_label/custom_label_condition.py +1 -1
- edc_form_label/form_label.py +2 -2
- edc_form_runners/exceptions.py +1 -1
- edc_form_runners/models/issue.py +3 -2
- edc_form_runners/site.py +2 -2
- edc_form_runners/templatetags/form_runners_extras.py +1 -1
- edc_form_runners/utils.py +5 -5
- edc_form_validators/applicable_field_validator.py +32 -32
- edc_form_validators/base_form_validator.py +1 -1
- edc_form_validators/extra_mixins/study_day_form_validator.py +1 -1
- edc_form_validators/many_to_many_field_validator.py +38 -43
- edc_form_validators/other_specify_field_validator.py +9 -17
- edc_form_validators/required_field_validator.py +34 -39
- edc_form_validators/test_case_mixin.py +5 -5
- edc_identifier/admin.py +1 -3
- edc_identifier/identifier.py +2 -3
- edc_identifier/model_mixins.py +5 -8
- edc_identifier/research_identifier.py +10 -12
- edc_identifier/short_identifier.py +1 -1
- edc_identifier/simple_identifier.py +22 -22
- edc_identifier/utils.py +1 -1
- edc_lab/admin/fieldsets.py +7 -9
- edc_lab/admin/modeladmin_mixins.py +5 -6
- edc_lab/form_validators/requisition_form_validator_mixin.py +2 -3
- edc_lab/forms/box_form.py +5 -11
- edc_lab/identifiers/aliquot_identifier.py +5 -8
- edc_lab/identifiers/prefix.py +2 -5
- edc_lab/lab/aliquot_creator.py +1 -2
- edc_lab/lab/aliquot_type.py +2 -4
- edc_lab/lab/manifest.py +5 -7
- edc_lab/lab/requisition_panel.py +2 -4
- edc_lab/lab/requisition_panel_group.py +5 -7
- edc_lab/model_mixins/requisition/requisition_model_mixin.py +5 -4
- edc_lab/model_mixins/shipping/manifest_model_mixin.py +6 -6
- edc_lab/model_mixins/shipping/verify_model_mixin.py +4 -3
- edc_lab/models/aliquot.py +1 -1
- edc_lab/models/box.py +2 -2
- edc_lab/models/box_item.py +1 -1
- edc_lab/models/box_type.py +1 -1
- edc_lab/models/manifest/manifest_item.py +1 -1
- edc_lab/pdf_reports/manifest_pdf_report.py +3 -7
- edc_lab/site_labs.py +3 -3
- edc_lab_dashboard/dashboard_templates.py +1 -1
- edc_lab_dashboard/view_mixins/box_view_mixin.py +4 -9
- edc_lab_dashboard/views/action_views/action_view.py +1 -2
- edc_lab_dashboard/views/action_views/manage_manifest_view.py +1 -1
- edc_lab_dashboard/views/action_views/manifest_view.py +9 -11
- edc_lab_dashboard/views/action_views/pack_view.py +11 -14
- edc_lab_results/calculate_missing.py +2 -2
- edc_lab_results/fieldsets.py +6 -6
- edc_lab_results/model_mixin_factories/__init__.py +2 -2
- edc_lab_results/model_mixin_factories/reportable_result_model_mixin_factory.py +7 -9
- edc_lab_results/model_mixin_factories/result_model_mixin_factory.py +7 -9
- edc_lab_results/model_mixins/fbg_model_mixin.py +1 -1
- edc_lab_results/model_mixins/glucose_model_mixin.py +1 -1
- edc_label/admin.py +1 -3
- edc_label/label.py +2 -4
- edc_label/label_template.py +1 -1
- edc_label/subject_label.py +1 -3
- edc_list_data/admin.py +3 -5
- edc_list_data/load_list_data.py +1 -1
- edc_list_data/load_model_data.py +1 -3
- edc_list_data/model_mixins.py +3 -5
- edc_list_data/preload_data.py +2 -4
- edc_list_data/site_list_data.py +6 -7
- edc_listboard/filters/listboard_filter.py +2 -2
- edc_listboard/views/listboard_view.py +1 -3
- edc_locator/models.py +2 -2
- edc_locator/view_mixins/subject_locator_view_mixins.py +2 -2
- edc_ltfu/action_items.py +1 -1
- edc_ltfu/model_mixins.py +0 -2
- edc_ltfu/models.py +4 -4
- edc_metadata/admin/modeladmin_mixins.py +1 -1
- edc_metadata/admin/requisition_metadata.py +2 -4
- edc_metadata/metadata/crf_metadata_getter.py +1 -3
- edc_metadata/metadata/requisition_metadata_getter.py +1 -3
- edc_metadata/metadata_handler.py +2 -2
- edc_metadata/metadata_helper/metadata_helper_mixin.py +2 -3
- edc_metadata/metadata_mixins/source_model_metadata_mixin.py +2 -2
- edc_metadata/metadata_refresher.py +1 -1
- edc_metadata/metadata_rules/crf/crf_rule_group.py +3 -5
- edc_metadata/metadata_rules/logic.py +1 -1
- edc_metadata/metadata_rules/requisition/requisition_rule.py +4 -4
- edc_metadata/metadata_rules/requisition/requisition_rule_group.py +2 -2
- edc_metadata/metadata_rules/rule_evaluator.py +5 -6
- edc_metadata/metadata_rules/rule_group_metaclass.py +2 -3
- edc_metadata/metadata_rules/site.py +6 -7
- edc_metadata/metadata_updater.py +2 -2
- edc_metadata/metadata_wrappers/metadata_wrapper.py +4 -4
- edc_metadata/model_mixins/creates/creates_metadata_model_mixin.py +6 -7
- edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +2 -2
- edc_metadata/model_mixins/updates/updates_metadata_model_mixin.py +2 -2
- edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +2 -2
- edc_metadata/models/crf_metadata.py +27 -29
- edc_metadata/models/crf_metadata_model_mixin.py +1 -1
- edc_metadata/models/requisition_metadata.py +29 -31
- edc_metadata/stubs.py +17 -17
- edc_metadata/utils.py +4 -4
- edc_model/__init__.py +2 -2
- edc_model/models/historical_records.py +2 -2
- edc_model/models/signals.py +1 -1
- edc_model/models/url_model_mixin.py +1 -1
- edc_model/utils.py +0 -2
- edc_model_admin/dashboard/model_admin_dashboard_mixin.py +1 -3
- edc_model_admin/history/model_admin_simple_history.py +7 -9
- edc_model_admin/mixins/base_model_admin_redirect_mixin.py +4 -6
- edc_model_admin/mixins/model_admin_limit_to_selected_foreignkey.py +2 -2
- edc_model_admin/mixins/model_admin_model_redirect_mixin.py +2 -10
- edc_model_admin/mixins/model_admin_next_url_redirect_mixin.py +8 -9
- edc_model_admin/utils.py +6 -9
- edc_model_form/mixins/__init__.py +1 -1
- edc_model_form/mixins/base_model_form_mixin.py +1 -1
- edc_model_to_dataframe/model_to_dataframe.py +2 -4
- edc_navbar/site_navbars.py +2 -2
- edc_navbar/system_checks.py +1 -1
- edc_notification/mailing_list_manager.py +5 -8
- edc_notification/management/commands/list_recipients_by_notification.py +1 -1
- edc_notification/models/__init__.py +4 -2
- edc_notification/notification/graded_event_notification.py +2 -4
- edc_notification/notification/model_notification.py +1 -3
- edc_notification/notification/notification.py +14 -17
- edc_notification/site_notifications.py +7 -7
- edc_notification/stubs.py +6 -6
- edc_notification/update_mailing_lists_in_m2m.py +2 -2
- edc_offstudy/action_items.py +2 -2
- edc_offstudy/model_mixins/offstudy_model_mixin.py +1 -1
- edc_offstudy/models.py +1 -1
- edc_pdf_reports/crf_pdf_report.py +2 -2
- edc_pdf_reports/model_mixins.py +2 -2
- edc_pdf_reports/report.py +4 -5
- edc_pdf_reports/utils.py +1 -1
- edc_pdutils/dataframes/get_subject_consent.py +1 -3
- edc_pdutils/df_exporters/csv_exporter.py +5 -7
- edc_pdutils/df_exporters/tables_exporter.py +2 -2
- edc_pdutils/df_handlers/crf_df_handler.py +1 -2
- edc_pdutils/dialects/crf_dialect.py +3 -3
- edc_pdutils/management/commands/export_models.py +6 -7
- edc_pdutils/site_values_mappings.py +2 -2
- edc_pdutils/utils/datetime_to_date.py +1 -2
- edc_pdutils/utils/refresh_model_from_dataframe.py +1 -3
- edc_pdutils/utils/table_names.py +2 -4
- edc_pdutils/utils/undash.py +1 -1
- edc_pharmacy/admin/medication/assignment_admin.py +2 -4
- edc_pharmacy/admin/medication/dosage_guideline_admin.py +2 -4
- edc_pharmacy/admin/medication/formulation_admin.py +3 -5
- edc_pharmacy/admin/medication/medication_admin.py +3 -5
- edc_pharmacy/admin/prescription/rx_refill_admin.py +7 -9
- edc_pharmacy/admin/stock/lot_admin.py +5 -7
- edc_pharmacy/admin/stock/order_admin.py +2 -2
- edc_pharmacy/admin/stock/order_item_admin.py +6 -6
- edc_pharmacy/admin/stock/receive_admin.py +1 -1
- edc_pharmacy/admin/stock/receive_item_admin.py +2 -2
- edc_pharmacy/admin/stock/stock_request_admin.py +4 -6
- edc_pharmacy/dosage_calculator.py +4 -4
- edc_pharmacy/form_validators/crf/study_medication_form_validator.py +8 -8
- edc_pharmacy/forms/stock/stock_request_form.py +2 -4
- edc_pharmacy/model_mixins/study_medication_crf_model_mixin.py +2 -2
- edc_pharmacy/models/medication/formulation.py +3 -4
- edc_pharmacy/models/medication/medication.py +1 -2
- edc_pharmacy/models/prescription/rx.py +2 -2
- edc_pharmacy/models/prescription/rx_refill.py +7 -9
- edc_pharmacy/models/reports/stock_availability.py +3 -4
- edc_pharmacy/models/stock/confirmation_at_site.py +1 -3
- edc_pharmacy/models/stock/order.py +1 -2
- edc_pharmacy/models/stock/receive.py +3 -4
- edc_pharmacy/models/stock/receive_item.py +2 -3
- edc_pharmacy/models/stock/stock.py +1 -2
- edc_pharmacy/models/stock/stock_adjustment.py +1 -2
- edc_pharmacy/models/stock/stock_request.py +4 -5
- edc_pharmacy/models/storage/box.py +1 -1
- edc_pharmacy/models/storage/items/container_model_mixin.py +1 -1
- edc_pharmacy/models/storage/room.py +1 -1
- edc_pharmacy/models/storage/shelf.py +1 -1
- edc_pharmacy/models/storage/utils.py +15 -16
- edc_pharmacy/prescribe/create_prescription.py +5 -5
- edc_pharmacy/refill/refill_creator.py +1 -1
- edc_pharmacy/sample_usb_printing/usb_printing.py +1 -1
- edc_pharmacy/utils/__init__.py +1 -1
- edc_pharmacy/utils/confirm_stock.py +3 -3
- edc_pharmacy/utils/confirm_stock_at_site.py +9 -8
- edc_pharmacy/utils/dispense.py +5 -8
- edc_pharmacy/utils/format_qty.py +3 -3
- edc_pharmacy/utils/get_codenames.py +1 -1
- edc_pharmacy/utils/miscellaneous.py +1 -1
- edc_pharmacy/utils/process_repack_request.py +18 -19
- edc_pharmacy/utils/process_repack_request_queryset.py +0 -2
- edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -3
- edc_pharmacy/views/add_to_storage_bin_view.py +1 -1
- edc_pharmacy/views/allocate_to_subject_view.py +2 -6
- edc_pharmacy/views/confirm_stock_from_instance_view.py +4 -4
- edc_pharmacy/views/confirm_stock_from_queryset_view.py +1 -5
- edc_pharmacy/views/confirmation_at_site_view.py +2 -3
- edc_pharmacy/views/dispense_view.py +1 -1
- edc_pharmacy/views/move_to_storage_bin_view.py +2 -3
- edc_pharmacy/views/print_labels_view.py +30 -31
- edc_pharmacy/views/transfer_stock_view.py +1 -1
- edc_prn/prn.py +1 -1
- edc_prn/site_prn_forms.py +1 -2
- edc_protocol_incident/action_items.py +2 -2
- edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +3 -3
- edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +3 -5
- edc_protocol_incident/modeladmin_mixins.py +3 -5
- edc_protocol_incident/models/protocol_deviation_violation.py +5 -5
- edc_protocol_incident/models/protocol_incident.py +5 -5
- edc_pylabels/site_label_configs.py +5 -5
- edc_qareports/model_mixins/qa_report_model_mixin.py +4 -2
- edc_qareports/models/qa_reports_log.py +1 -2
- edc_qareports/utils.py +1 -2
- edc_randomization/admin.py +3 -5
- edc_randomization/auth_objects.py +2 -3
- edc_randomization/blinding.py +1 -1
- edc_randomization/constants.py +2 -4
- edc_randomization/model_mixins.py +3 -3
- edc_randomization/randomization_list_importer.py +13 -14
- edc_randomization/randomization_list_verifier.py +11 -13
- edc_randomization/randomizer.py +2 -2
- edc_randomization/system_checks.py +1 -2
- edc_randomization/utils.py +5 -5
- edc_refusal/admin.py +1 -1
- edc_refusal/model_mixins.py +1 -1
- edc_refusal/utils.py +1 -1
- edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +2 -2
- edc_registration/modeladmin_mixins.py +4 -7
- edc_registration/models/registered_subject.py +7 -9
- edc_registration/utils.py +3 -4
- edc_reportable/data/grading_data/daids_july_2017.py +3 -3
- edc_reportable/evaluator.py +5 -5
- edc_reportable/formula.py +1 -1
- edc_reportable/reference_range_evaluator.py +3 -3
- edc_reportable/utils/convert_units.py +10 -12
- edc_reportable/utils/grading_data_model_cls.py +2 -2
- edc_reportable/utils/grading_exception_model_cls.py +2 -2
- edc_reportable/utils/molecular_weight_model_cls.py +2 -2
- edc_reportable/utils/normal_data_model_cls.py +2 -2
- edc_reportable/utils/reference_range_colllection_model_cls.py +2 -2
- edc_screening/age_evaluator.py +2 -4
- edc_screening/eligibility.py +1 -1
- edc_screening/form_validator_mixins.py +2 -2
- edc_screening/model_mixins/screening_methods_model_mixin.py +1 -1
- edc_screening/screening_eligibility.py +1 -1
- edc_screening/utils.py +4 -6
- edc_search/model_mixins.py +1 -1
- edc_search/search_slug.py +1 -3
- edc_search/updater.py +1 -1
- edc_sites/admin/site_model_admin_mixin.py +2 -2
- edc_sites/model_mixins/site_model_mixin.py +1 -2
- edc_sites/modelform_mixins.py +2 -2
- edc_sites/models/__init__.py +1 -1
- edc_sites/models/site_profile.py +4 -4
- edc_sites/site.py +24 -32
- edc_sites/system_checks.py +1 -1
- edc_sites/utils/get_message_text.py +1 -1
- edc_sites/utils/valid_site_for_subject_or_raise.py +5 -6
- edc_subject_dashboard/requisition_report.py +4 -5
- edc_subject_dashboard/requisition_verifier.py +4 -2
- edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +16 -17
- edc_subject_dashboard/view_utils/__init__.py +1 -1
- edc_subject_dashboard/view_utils/crf_button.py +1 -3
- edc_subject_dashboard/view_utils/subject_consent_dashboard_button.py +2 -2
- edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +2 -2
- edc_subject_dashboard/view_utils/timepoint_status_button.py +1 -4
- edc_subject_dashboard/views/requisition_print_actions_view.py +2 -2
- edc_subject_dashboard/views/subject_dashboard_view.py +1 -1
- edc_timepoint/model_mixins.py +2 -2
- edc_transfer/action_items.py +1 -1
- edc_transfer/model_mixins.py +4 -3
- edc_transfer/modeladmin_mixins.py +3 -6
- edc_unblinding/action_items.py +2 -2
- edc_unblinding/models/unblinding_request.py +3 -3
- edc_unblinding/models/unblinding_review.py +3 -3
- edc_utils/__init__.py +6 -5
- edc_utils/age.py +1 -1
- edc_utils/celery.py +3 -8
- edc_utils/get_static_file.py +1 -1
- edc_utils/text.py +5 -6
- edc_view_utils/__init__.py +3 -3
- edc_view_utils/dashboard_model_button.py +4 -4
- edc_view_utils/model_button.py +7 -8
- edc_view_utils/perms.py +3 -3
- edc_visit_schedule/action_items.py +2 -2
- edc_visit_schedule/admin/list_filters.py +11 -9
- edc_visit_schedule/admin/subject_schedule_history_admin.py +13 -15
- edc_visit_schedule/admin/visit_schedule_admin.py +7 -7
- edc_visit_schedule/fieldsets.py +4 -6
- edc_visit_schedule/management/commands/find_invalid_onschedules.py +1 -1
- edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +3 -1
- edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +1 -1
- edc_visit_schedule/modelform_mixins/__init__.py +1 -1
- edc_visit_schedule/modelform_mixins/off_schedule_modelform_mixin.py +1 -2
- edc_visit_schedule/models/subject_schedule_history.py +2 -1
- edc_visit_schedule/models/visit_schedule.py +2 -2
- edc_visit_schedule/schedule/schedule.py +11 -12
- edc_visit_schedule/schedule/visit_collection.py +4 -3
- edc_visit_schedule/schedule/window.py +19 -12
- edc_visit_schedule/site_visit_schedules.py +9 -9
- edc_visit_schedule/subject_schedule.py +6 -7
- edc_visit_schedule/system_checks.py +1 -1
- edc_visit_schedule/view_mixins.py +1 -1
- edc_visit_schedule/visit/crf.py +3 -7
- edc_visit_schedule/visit/requisition.py +2 -2
- edc_visit_schedule/visit/visit.py +6 -7
- edc_visit_schedule/visit/window_period.py +8 -8
- edc_visit_schedule/visit_schedule/schedules_collection.py +2 -5
- edc_visit_tracking/action_items.py +11 -13
- edc_visit_tracking/form_validators/visit_form_validator.py +5 -5
- edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +3 -4
- edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +2 -2
- edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +2 -3
- edc_visit_tracking/model_mixins/utils.py +1 -1
- edc_visit_tracking/model_mixins/visit_model_mixin/previous_visit_model_mixin.py +2 -2
- edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +3 -3
- edc_visit_tracking/modeladmin_mixins/crf_model_admin_mixin.py +6 -4
- edc_visit_tracking/modeladmin_mixins/visit_model_admin_mixin.py +6 -7
- edc_visit_tracking/modelform_mixins/crf/visit_tracking_crf_modelform_mixin.py +4 -5
- edc_visit_tracking/modelform_mixins/visit_tracking_modelform_mixin.py +3 -4
- edc_visit_tracking/models/subject_visit.py +1 -1
- edc_visit_tracking/models/subject_visit_missed.py +1 -1
- edc_visit_tracking/stubs.py +7 -7
- edc_visit_tracking/typing_stubs.py +11 -11
- edc_visit_tracking/utils.py +5 -5
- edc_visit_tracking/view_utils/related_visit_button.py +5 -5
- edc_vitals/calculators/bmi.py +1 -1
- edc_vitals/form_validators/blood_pressure_form_validator_mixin.py +8 -10
- edc_vitals/form_validators/bmi_form_validator_mixin.py +1 -1
- edc_vitals/form_validators/weight_height_with_bmi_form_validator_mixin.py +5 -2
- edc_vitals/model_mixins/blood_pressure_model_mixin.py +3 -4
- edc_vitals/model_mixins/weight_height_bmi_model_mixin.py +4 -4
- edc_vitals/utils.py +1 -1
- edc_vitals/validators.py +1 -1
- {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/WHEEL +0 -0
- {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/licenses/LICENSE +0 -0
edc_export/models/plan.py
CHANGED
|
@@ -21,15 +21,15 @@ class Plan(BaseUuidModel):
|
|
|
21
21
|
|
|
22
22
|
model = models.CharField(max_length=50)
|
|
23
23
|
|
|
24
|
-
field_names = models.TextField(max_length=500, blank=True,
|
|
24
|
+
field_names = models.TextField(max_length=500, blank=True, default="")
|
|
25
25
|
|
|
26
|
-
header_labels = models.TextField(max_length=500, blank=True,
|
|
26
|
+
header_labels = models.TextField(max_length=500, blank=True, default="")
|
|
27
27
|
|
|
28
|
-
lookups = models.TextField(max_length=500, blank=True,
|
|
28
|
+
lookups = models.TextField(max_length=500, blank=True, default="")
|
|
29
29
|
|
|
30
30
|
model_type = models.CharField(max_length=25, choices=MODEL_TYPES, default="plain")
|
|
31
31
|
|
|
32
|
-
excluded_field_names = models.TextField(max_length=500, blank=True,
|
|
32
|
+
excluded_field_names = models.TextField(max_length=500, blank=True, default="")
|
|
33
33
|
|
|
34
34
|
header = models.BooleanField(verbose_name="Include header", default=True)
|
|
35
35
|
|
|
@@ -34,7 +34,7 @@ class UploadExportReceiptFile(BaseUuidModel):
|
|
|
34
34
|
|
|
35
35
|
total = models.IntegerField(default=0, editable=False)
|
|
36
36
|
|
|
37
|
-
errors = models.TextField(editable=False,
|
|
37
|
+
errors = models.TextField(editable=False, default="")
|
|
38
38
|
|
|
39
39
|
receipt_datetime = models.DateTimeField(editable=False, null=True)
|
|
40
40
|
|
|
@@ -74,4 +74,4 @@ class UploadExportReceiptFile(BaseUuidModel):
|
|
|
74
74
|
self.errors = "; ".join(error_list)
|
|
75
75
|
|
|
76
76
|
class Meta(BaseUuidModel.Meta):
|
|
77
|
-
indexes =
|
|
77
|
+
indexes = (Index(fields=["created"]),)
|
edc_export/utils.py
CHANGED
edc_facility/facility.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from operator import methodcaller
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
from zoneinfo import ZoneInfo
|
|
7
7
|
|
|
8
8
|
import arrow
|
|
@@ -42,7 +42,7 @@ class Facility:
|
|
|
42
42
|
self.days = []
|
|
43
43
|
self.name = name
|
|
44
44
|
if not name:
|
|
45
|
-
raise FacilityError(f"Name cannot be None. See {
|
|
45
|
+
raise FacilityError(f"Name cannot be None. See {self!r}")
|
|
46
46
|
self.best_effort_available_datetime = (
|
|
47
47
|
True if best_effort_available_datetime is None else best_effort_available_datetime
|
|
48
48
|
)
|
|
@@ -53,7 +53,7 @@ class Facility:
|
|
|
53
53
|
day = weekday(day)
|
|
54
54
|
self.days.append(day)
|
|
55
55
|
self.slots = slots or [99999 for _ in self.days]
|
|
56
|
-
self.config = dict(zip([str(d) for d in self.days], self.slots))
|
|
56
|
+
self.config = dict(zip([str(d) for d in self.days], self.slots, strict=False))
|
|
57
57
|
self.holidays = self.holiday_cls()
|
|
58
58
|
|
|
59
59
|
def __repr__(self):
|
|
@@ -94,7 +94,7 @@ class Facility:
|
|
|
94
94
|
@staticmethod
|
|
95
95
|
def get_arr_span(
|
|
96
96
|
suggested_arr, forward_delta, reverse_delta
|
|
97
|
-
) ->
|
|
97
|
+
) -> tuple[list[Arrow | Any], Arrow, Arrow]:
|
|
98
98
|
"""Returns a list of arrow objects in a custom ordered.
|
|
99
99
|
Objects are ordered around the suggested date. For example,
|
|
100
100
|
"""
|
|
@@ -111,7 +111,7 @@ class Facility:
|
|
|
111
111
|
span_lt = sorted(span_lt, key=methodcaller("date"), reverse=True)
|
|
112
112
|
span_gt = [arw for arw in span if arw.date() > suggested_arr.date()]
|
|
113
113
|
arr_span = []
|
|
114
|
-
max_len = len(
|
|
114
|
+
max_len = max(len(span_lt), len(span_gt))
|
|
115
115
|
for i in range(0, max_len):
|
|
116
116
|
try:
|
|
117
117
|
item = span_lt.pop()
|
|
@@ -183,7 +183,7 @@ class Facility:
|
|
|
183
183
|
f"No available appointment dates at facility for period. "
|
|
184
184
|
f"Got no available dates within {reverse_delta.days}-"
|
|
185
185
|
f"{forward_delta.days} days of {formatted_date}. "
|
|
186
|
-
f"Facility is {
|
|
186
|
+
f"Facility is {self!r}."
|
|
187
187
|
)
|
|
188
188
|
available_arr = arrow.Arrow.fromdatetime(
|
|
189
189
|
datetime.combine(available_arr.date(), suggested_arr.time())
|
edc_facility/holidays.py
CHANGED
|
@@ -80,11 +80,8 @@ class Holidays:
|
|
|
80
80
|
if not self._holidays:
|
|
81
81
|
if holidays_disabled():
|
|
82
82
|
self._holidays = self.model_cls.objects.none()
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
raise HolidayError(
|
|
86
|
-
f"No holidays found for '{self.country}. See {self.model}."
|
|
87
|
-
)
|
|
83
|
+
elif not self.model_cls.objects.filter(country=self.country).exists():
|
|
84
|
+
raise HolidayError(f"No holidays found for '{self.country}. See {self.model}.")
|
|
88
85
|
self._holidays = self.model_cls.objects.filter(country=self.country)
|
|
89
86
|
return self._holidays
|
|
90
87
|
|
edc_facility/import_holidays.py
CHANGED
|
@@ -4,7 +4,7 @@ import csv
|
|
|
4
4
|
import sys
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
from django.conf import settings
|
|
10
10
|
from django.core.exceptions import ObjectDoesNotExist
|
|
@@ -54,7 +54,7 @@ def import_holidays(verbose: bool | None = None, test: bool | None = None) -> No
|
|
|
54
54
|
|
|
55
55
|
def check_for_duplicates_in_file(path) -> list:
|
|
56
56
|
"""Returns a list of records."""
|
|
57
|
-
with open(path
|
|
57
|
+
with open(path) as f:
|
|
58
58
|
reader = csv.DictReader(f, fieldnames=["local_date", "label", "country"])
|
|
59
59
|
recs = [(row["local_date"], row["country"]) for row in reader]
|
|
60
60
|
if len(recs) != len(list(set(recs))):
|
|
@@ -63,7 +63,7 @@ def check_for_duplicates_in_file(path) -> list:
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
def import_file(path: str, recs: list, model_cls: Holiday):
|
|
66
|
-
with open(path
|
|
66
|
+
with open(path) as f:
|
|
67
67
|
reader = csv.DictReader(f, fieldnames=["local_date", "label", "country"])
|
|
68
68
|
for index, row in tqdm(enumerate(reader), total=len(recs)):
|
|
69
69
|
if index == 0:
|
|
@@ -72,7 +72,7 @@ def import_file(path: str, recs: list, model_cls: Holiday):
|
|
|
72
72
|
local_date = datetime.strptime(row["local_date"], "%Y-%m-%d").date()
|
|
73
73
|
except ValueError as e:
|
|
74
74
|
raise HolidayImportError(
|
|
75
|
-
f"Invalid format when importing from
|
|
75
|
+
f"Invalid format when importing from {path}. Got '{e}'"
|
|
76
76
|
)
|
|
77
77
|
else:
|
|
78
78
|
try:
|
|
@@ -86,7 +86,7 @@ def import_file(path: str, recs: list, model_cls: Holiday):
|
|
|
86
86
|
obj.save()
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
def import_for_tests(model_cls:
|
|
89
|
+
def import_for_tests(model_cls: type[Holiday]):
|
|
90
90
|
year = get_utcnow().year
|
|
91
91
|
country = sites.get_current_country()
|
|
92
92
|
if not country:
|
|
@@ -115,7 +115,7 @@ def import_for_tests(model_cls: Type[Holiday]):
|
|
|
115
115
|
local_date = datetime.strptime(row[LOCAL_DATE], "%Y-%m-%d").date()
|
|
116
116
|
except ValueError as e:
|
|
117
117
|
raise HolidayImportError(
|
|
118
|
-
f"Invalid format when importing holidays (test).
|
|
118
|
+
f"Invalid format when importing holidays (test). Got '{e}'"
|
|
119
119
|
)
|
|
120
120
|
else:
|
|
121
121
|
objs.append(
|
edc_facility/model_mixins.py
CHANGED
edc_facility/models/holiday.py
CHANGED
edc_facility/utils.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from django.apps import apps as django_apps
|
|
6
6
|
from django.conf import settings
|
|
@@ -16,7 +16,7 @@ def get_holiday_model() -> str:
|
|
|
16
16
|
return getattr(settings, "EDC_FACILITY_HOLIDAY_MODEL", "edc_facility.holiday")
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def get_holiday_model_cls() ->
|
|
19
|
+
def get_holiday_model_cls() -> type[Holiday]:
|
|
20
20
|
return django_apps.get_model(get_holiday_model())
|
|
21
21
|
|
|
22
22
|
|
|
@@ -44,7 +44,7 @@ def get_facility(name: str = None) -> Facility:
|
|
|
44
44
|
return facility
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def get_health_facility_model_cls() ->
|
|
47
|
+
def get_health_facility_model_cls() -> type[HealthFacility]:
|
|
48
48
|
return django_apps.get_model(get_health_facility_model())
|
|
49
49
|
|
|
50
50
|
|
edc_fieldsets/fieldsets.py
CHANGED
|
@@ -65,7 +65,7 @@ class Fieldsets:
|
|
|
65
65
|
try:
|
|
66
66
|
fields = copy.copy(self.fieldsets_asdict[section]["fields"])
|
|
67
67
|
except KeyError:
|
|
68
|
-
raise FieldsetError("Invalid fieldset section. Got {}"
|
|
68
|
+
raise FieldsetError(f"Invalid fieldset section. Got {section}")
|
|
69
69
|
return list(fields)
|
|
70
70
|
|
|
71
71
|
@staticmethod
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from importlib.metadata import version
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from django.apps import apps as django_apps
|
|
6
5
|
from django.conf import settings
|
|
@@ -54,8 +53,8 @@ class FormsReference:
|
|
|
54
53
|
|
|
55
54
|
def to_file(
|
|
56
55
|
self,
|
|
57
|
-
path:
|
|
58
|
-
overwrite:
|
|
56
|
+
path: str | None = None,
|
|
57
|
+
overwrite: bool | None = None,
|
|
59
58
|
pad: int | None = None,
|
|
60
59
|
):
|
|
61
60
|
pad = pad if pad is not None else 2
|
|
@@ -77,9 +76,8 @@ class FormsReference:
|
|
|
77
76
|
if anchor not in self._anchors:
|
|
78
77
|
self._anchors.append(anchor)
|
|
79
78
|
break
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
anchor = anchor_orig + f"-{index}"
|
|
79
|
+
index += 1
|
|
80
|
+
anchor = anchor_orig + f"-{index}"
|
|
83
81
|
return anchor
|
|
84
82
|
|
|
85
83
|
@property
|
|
@@ -108,8 +106,7 @@ class FormsReference:
|
|
|
108
106
|
describer.markdown.append("\n")
|
|
109
107
|
anchor = f"{self.get_anchor(describer.anchor)}"
|
|
110
108
|
toc.append(
|
|
111
|
-
f'{index + 1}. <a href="#{anchor}">'
|
|
112
|
-
f"{describer.verbose_name}</a>"
|
|
109
|
+
f'{index + 1}. <a href="#{anchor}">{describer.verbose_name}</a>'
|
|
113
110
|
)
|
|
114
111
|
markdown.extend(describer.markdown)
|
|
115
112
|
markdown.append(f"{self.h4} Requisitions\n")
|
|
@@ -23,7 +23,7 @@ def make_forms_reference(
|
|
|
23
23
|
path: str | None = None,
|
|
24
24
|
):
|
|
25
25
|
module = import_module(app_label)
|
|
26
|
-
admin_site = getattr(
|
|
26
|
+
admin_site = getattr(module.admin_site, admin_site_name)
|
|
27
27
|
visit_schedule = site_visit_schedules.get_visit_schedule(visit_schedule_name)
|
|
28
28
|
title = title or _("%(title_app)s Forms Reference") % dict(title_app=app_label.upper())
|
|
29
29
|
sys.stdout.write(
|
|
@@ -27,7 +27,7 @@ def update_forms_reference(
|
|
|
27
27
|
module = import_module(app_label)
|
|
28
28
|
default_doc_folder = Path(settings.BASE_DIR / "docs")
|
|
29
29
|
filename = filename or "forms_reference.md"
|
|
30
|
-
admin_site = getattr(
|
|
30
|
+
admin_site = getattr(module.admin_site, admin_site_name)
|
|
31
31
|
visit_schedule = site_visit_schedules.get_visit_schedule(visit_schedule_name)
|
|
32
32
|
title = title or _("%(title_app)s Forms Reference") % dict(title_app=app_label.upper())
|
|
33
33
|
sys.stdout.write(
|
edc_form_label/form_label.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from .custom_label_condition import CustomFormLabelError
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ class FormLabel:
|
|
|
10
10
|
def __init__(self, field=None, custom_label=None, condition_cls=None):
|
|
11
11
|
self.field = field
|
|
12
12
|
self.custom_label = custom_label
|
|
13
|
-
self.condition_cls:
|
|
13
|
+
self.condition_cls: type[CustomLabelCondition] = condition_cls
|
|
14
14
|
|
|
15
15
|
def get_form_label(self, request=None, obj=None, model=None, form=None):
|
|
16
16
|
"""Returns a customized form label, if condition is met,
|
edc_form_runners/exceptions.py
CHANGED
edc_form_runners/models/issue.py
CHANGED
|
@@ -57,7 +57,8 @@ class Issue(BaseUuidModel):
|
|
|
57
57
|
name="unique_label_lower_subject_identifier_etc",
|
|
58
58
|
)
|
|
59
59
|
]
|
|
60
|
-
indexes =
|
|
60
|
+
indexes = (
|
|
61
|
+
*BaseUuidModel.Meta.indexes,
|
|
61
62
|
Index(fields=["label_lower", "field_name", "panel_name", "short_message"]),
|
|
62
63
|
Index(
|
|
63
64
|
fields=[
|
|
@@ -69,4 +70,4 @@ class Issue(BaseUuidModel):
|
|
|
69
70
|
"short_message",
|
|
70
71
|
],
|
|
71
72
|
),
|
|
72
|
-
|
|
73
|
+
)
|
edc_form_runners/site.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
4
|
from copy import deepcopy
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from django.apps import apps as django_apps
|
|
8
8
|
from django.core.management.color import color_style
|
|
@@ -25,7 +25,7 @@ __all__ = ["site_form_runners"]
|
|
|
25
25
|
|
|
26
26
|
class SiteFormRunners:
|
|
27
27
|
def __init__(self):
|
|
28
|
-
self.registry: dict[str,
|
|
28
|
+
self.registry: dict[str, type[FormRunner]] = {}
|
|
29
29
|
self.loaded = False
|
|
30
30
|
|
|
31
31
|
def register(self, runner=None):
|
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|
|
12
12
|
from edc_crf.model_mixins import CrfModelMixin
|
|
13
13
|
from edc_metadata.models import CrfMetadata, RequisitionMetadata
|
|
14
14
|
|
|
15
|
-
class Model(CrfModelMixin, models.Model): ...
|
|
15
|
+
class Model(CrfModelMixin, models.Model): ...
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
register = template.Library()
|
edc_form_runners/utils.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import cache
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from django.apps import apps as django_apps
|
|
7
7
|
from django.conf import settings
|
|
@@ -42,7 +42,7 @@ def get_issue_model_cls() -> Issue:
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
@cache
|
|
45
|
-
def get_modeladmins_from_admin_sites() -> dict[str,
|
|
45
|
+
def get_modeladmins_from_admin_sites() -> dict[str, type[ModelAdmin]]:
|
|
46
46
|
registry = {}
|
|
47
47
|
for admin_site in admin.sites.all_sites:
|
|
48
48
|
registry.update(**get_modeladmins_from_admin_site(admin_site))
|
|
@@ -50,7 +50,7 @@ def get_modeladmins_from_admin_sites() -> dict[str, Type[ModelAdmin]]:
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
@cache
|
|
53
|
-
def get_modelforms_from_admin_site(admin_site) -> dict[str,
|
|
53
|
+
def get_modelforms_from_admin_site(admin_site) -> dict[str, type[ModelForm]]:
|
|
54
54
|
registry = {}
|
|
55
55
|
for admin_class in admin_site._registry.values():
|
|
56
56
|
registry.update({admin_class.model._meta.label_lower: admin_class.form})
|
|
@@ -58,14 +58,14 @@ def get_modelforms_from_admin_site(admin_site) -> dict[str, Type[ModelForm]]:
|
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
@cache
|
|
61
|
-
def get_modeladmins_from_admin_site(admin_site) -> dict[str,
|
|
61
|
+
def get_modeladmins_from_admin_site(admin_site) -> dict[str, type[ModelAdmin]]:
|
|
62
62
|
registry = {}
|
|
63
63
|
for admin_class in admin_site._registry.values():
|
|
64
64
|
registry.update({admin_class.model._meta.label_lower: admin_class})
|
|
65
65
|
return registry
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def get_modeladmin_cls(model_name: str) ->
|
|
68
|
+
def get_modeladmin_cls(model_name: str) -> type[ModelAdmin]:
|
|
69
69
|
return get_modeladmins_from_admin_sites().get(model_name)
|
|
70
70
|
|
|
71
71
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
from edc_constants.constants import NOT_APPLICABLE
|
|
4
4
|
|
|
@@ -13,8 +13,8 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
13
13
|
def raise_applicable(
|
|
14
14
|
self,
|
|
15
15
|
field,
|
|
16
|
-
msg:
|
|
17
|
-
applicable_msg:
|
|
16
|
+
msg: str | None = None,
|
|
17
|
+
applicable_msg: str | None = None,
|
|
18
18
|
) -> None:
|
|
19
19
|
message = {field: applicable_msg or f"This field is applicable. {msg or ''}".strip()}
|
|
20
20
|
self.raise_validation_error(message, APPLICABLE_ERROR)
|
|
@@ -22,8 +22,8 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
22
22
|
def raise_not_applicable(
|
|
23
23
|
self,
|
|
24
24
|
field,
|
|
25
|
-
msg:
|
|
26
|
-
not_applicable_msg:
|
|
25
|
+
msg: str | None = None,
|
|
26
|
+
not_applicable_msg: str | None = None,
|
|
27
27
|
) -> None:
|
|
28
28
|
message = {
|
|
29
29
|
field: not_applicable_msg or f"This field is not applicable. {msg or ''}".strip()
|
|
@@ -35,11 +35,11 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
35
35
|
*responses: Any,
|
|
36
36
|
field: str = None,
|
|
37
37
|
field_applicable: str = None,
|
|
38
|
-
inverse:
|
|
39
|
-
is_instance_field:
|
|
40
|
-
msg:
|
|
41
|
-
applicable_msg:
|
|
42
|
-
not_applicable_msg:
|
|
38
|
+
inverse: bool | None = None,
|
|
39
|
+
is_instance_field: bool | None = None,
|
|
40
|
+
msg: str | None = None,
|
|
41
|
+
applicable_msg: str | None = None,
|
|
42
|
+
not_applicable_msg: str | None = None,
|
|
43
43
|
not_applicable_value=None,
|
|
44
44
|
) -> bool:
|
|
45
45
|
return self.applicable(
|
|
@@ -59,11 +59,11 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
59
59
|
*responses: Any,
|
|
60
60
|
field: str = None,
|
|
61
61
|
field_applicable: str = None,
|
|
62
|
-
inverse:
|
|
63
|
-
is_instance_field:
|
|
64
|
-
msg:
|
|
65
|
-
applicable_msg:
|
|
66
|
-
not_applicable_msg:
|
|
62
|
+
inverse: bool | None = None,
|
|
63
|
+
is_instance_field: bool | None = None,
|
|
64
|
+
msg: str | None = None,
|
|
65
|
+
applicable_msg: str | None = None,
|
|
66
|
+
not_applicable_msg: str | None = None,
|
|
67
67
|
not_applicable_value=None,
|
|
68
68
|
) -> bool:
|
|
69
69
|
return self.not_applicable(
|
|
@@ -87,7 +87,7 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
87
87
|
field_applicable_value = self.get(field_applicable)
|
|
88
88
|
|
|
89
89
|
if field_value in responses and (
|
|
90
|
-
|
|
90
|
+
field_applicable_value and field_applicable_value is not None
|
|
91
91
|
):
|
|
92
92
|
self.raise_not_applicable(field_applicable)
|
|
93
93
|
return False
|
|
@@ -97,11 +97,11 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
97
97
|
*responses: Any,
|
|
98
98
|
field: str = None,
|
|
99
99
|
field_applicable: str = None,
|
|
100
|
-
inverse:
|
|
101
|
-
is_instance_field:
|
|
102
|
-
msg:
|
|
103
|
-
applicable_msg:
|
|
104
|
-
not_applicable_msg:
|
|
100
|
+
inverse: bool | None = None,
|
|
101
|
+
is_instance_field: bool | None = None,
|
|
102
|
+
msg: str | None = None,
|
|
103
|
+
applicable_msg: str | None = None,
|
|
104
|
+
not_applicable_msg: str | None = None,
|
|
105
105
|
not_applicable_value=None,
|
|
106
106
|
) -> bool:
|
|
107
107
|
"""Returns False or raises a validation error for field
|
|
@@ -135,11 +135,11 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
135
135
|
*responses: Any,
|
|
136
136
|
field: str = None,
|
|
137
137
|
field_applicable: str = None,
|
|
138
|
-
inverse:
|
|
139
|
-
is_instance_field:
|
|
140
|
-
msg:
|
|
141
|
-
applicable_msg:
|
|
142
|
-
not_applicable_msg:
|
|
138
|
+
inverse: bool | None = None,
|
|
139
|
+
is_instance_field: bool | None = None,
|
|
140
|
+
msg: str | None = None,
|
|
141
|
+
applicable_msg: str | None = None,
|
|
142
|
+
not_applicable_msg: str | None = None,
|
|
143
143
|
not_applicable_value=None,
|
|
144
144
|
) -> bool:
|
|
145
145
|
"""Returns False or raises a validation error for field
|
|
@@ -166,9 +166,9 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
166
166
|
self,
|
|
167
167
|
condition: bool,
|
|
168
168
|
field_applicable: str = None,
|
|
169
|
-
applicable_msg:
|
|
170
|
-
not_applicable_msg:
|
|
171
|
-
inverse:
|
|
169
|
+
applicable_msg: str | None = None,
|
|
170
|
+
not_applicable_msg: str | None = None,
|
|
171
|
+
inverse: bool | None = None,
|
|
172
172
|
not_applicable_value=None,
|
|
173
173
|
) -> bool:
|
|
174
174
|
inverse = True if inverse is None else inverse
|
|
@@ -189,9 +189,9 @@ class ApplicableFieldValidator(BaseFormValidator):
|
|
|
189
189
|
self,
|
|
190
190
|
condition: bool,
|
|
191
191
|
field_applicable: str = None,
|
|
192
|
-
applicable_msg:
|
|
193
|
-
not_applicable_msg:
|
|
194
|
-
inverse:
|
|
192
|
+
applicable_msg: str | None = None,
|
|
193
|
+
not_applicable_msg: str | None = None,
|
|
194
|
+
inverse: bool | None = None,
|
|
195
195
|
not_applicable_value=None,
|
|
196
196
|
) -> bool:
|
|
197
197
|
inverse = True if inverse is None else inverse
|
|
@@ -45,7 +45,7 @@ class BaseFormValidator:
|
|
|
45
45
|
self.data = {}
|
|
46
46
|
if cleaned_data is None:
|
|
47
47
|
raise ModelFormFieldValidatorError(
|
|
48
|
-
f"{
|
|
48
|
+
f"{self!r}. Expected a cleaned_data dictionary. Got None."
|
|
49
49
|
)
|
|
50
50
|
self.cleaned_data = copy(cleaned_data)
|
|
51
51
|
self.original_cleaned_data = copy(cleaned_data)
|
|
@@ -29,7 +29,7 @@ class StudyDayFormValidatorMixin:
|
|
|
29
29
|
except AttributeError:
|
|
30
30
|
pass
|
|
31
31
|
if not subject_identifier or self.subject_identifier:
|
|
32
|
-
raise ValueError(f"Subject identifier cannot be None. See {
|
|
32
|
+
raise ValueError(f"Subject identifier cannot be None. See {self!r}")
|
|
33
33
|
registered_subject_model_cls = django_apps.get_model(
|
|
34
34
|
"edc_registration.registeredsubject"
|
|
35
35
|
)
|