clinicedc 2.0.6__py3-none-any.whl → 2.0.7__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.6.dist-info → clinicedc-2.0.7.dist-info}/METADATA +2 -2
- {clinicedc-2.0.6.dist-info → clinicedc-2.0.7.dist-info}/RECORD +386 -335
- edc_action_item/action.py +1 -1
- edc_action_item/action_item_notification.py +2 -2
- edc_action_item/create_action_item.py +1 -1
- edc_action_item/decorators.py +1 -1
- edc_action_item/migrations/0001_initial.py +21 -22
- edc_action_item/migrations/0006_auto_20180707_1659.py +4 -4
- edc_action_item/migrations/0008_auto_20180809_0303.py +4 -4
- edc_action_item/migrations/0015_auto_20190114_0250.py +4 -4
- edc_action_item/migrations/0017_auto_20190305_0123.py +11 -30
- edc_action_item/migrations/0030_edcpermissions.py +3 -2
- edc_action_item/migrations/0039_alter_actionitem_auto_created_comment_and_more.py +398 -0
- edc_action_item/migrations/0040_alter_actionitem_report_datetime_and_more.py +34 -0
- edc_action_item/models/action_item.py +9 -4
- edc_action_item/models/action_model_mixin.py +4 -4
- edc_action_item/models/reference.py +2 -2
- edc_action_item/post_migrate_signals.py +1 -1
- edc_action_item/send_email.py +0 -85
- edc_adherence/migrations/0005_alter_nonadherencereasons_extra_value_and_more.py +36 -0
- edc_adherence/model_mixins.py +1 -1
- edc_adverse_event/migrations/0001_initial.py +5 -4
- edc_adverse_event/migrations/0002_auto_20190802_0059.py +3 -2
- edc_adverse_event/migrations/0008_auto_20220825_0451.py +3 -2
- edc_adverse_event/migrations/0009_auto_20220907_0157.py +3 -2
- edc_adverse_event/migrations/0016_alter_aeactionclassification_device_created_and_more.py +285 -0
- edc_adverse_event/model_mixins/ae_followup/ae_followup_fields_model_mixin.py +2 -2
- edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +6 -5
- edc_adverse_event/model_mixins/ae_special_interest/aesi_fields_model_mixin.py +2 -2
- edc_adverse_event/model_mixins/ae_susar/ae_susar_fields_model_mixin.py +2 -2
- edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +15 -11
- edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +5 -4
- edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +6 -3
- edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +2 -2
- edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +4 -3
- edc_adverse_event/modeladmin_mixins/death_report_admin_mixin.py +3 -3
- edc_adverse_event/models/signals.py +7 -7
- edc_adverse_event/templatetags/edc_adverse_event_extras.py +5 -4
- edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +3 -5
- edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +6 -8
- edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +2 -2
- edc_adverse_event/views/tmg/summary_listboard_view.py +3 -2
- edc_appointment/admin/appointment_admin.py +2 -2
- edc_appointment/admin/list_filters.py +2 -2
- edc_appointment/form_validators/appointment_form_validator.py +108 -82
- edc_appointment/migrations/0003_auto_20161127_2226.py +5 -6
- edc_appointment/migrations/0006_auto_20170106_2118.py +5 -5
- edc_appointment/migrations/0018_auto_20190305_0123.py +5 -12
- edc_appointment/migrations/0050_alter_appointment_appt_type_and_more.py +220 -0
- edc_appointment/model_mixins/appointment_fields_model_mixin.py +1 -2
- edc_appointment/model_mixins/window_period_model_mixin.py +6 -7
- edc_appointment/models/signals.py +44 -35
- edc_appointment/view_utils/appointment_button.py +2 -2
- edc_auth/admin/user_admin.py +1 -1
- edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +5 -5
- edc_auth/migrations/0012_auto_20191026_0034.py +3 -2
- edc_auth/migrations/0013_auto_20191026_0055.py +3 -2
- edc_auth/migrations/0025_permissions.py +3 -2
- edc_auth/migrations/0035_alter_edcpermissions_device_created_and_more.py +85 -0
- edc_auth/post_migrate_signals.py +1 -1
- edc_consent/actions.py +4 -5
- edc_consent/migrations/0001_initial.py +3 -2
- edc_consent/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_consent/model_mixins/consent_extension_model_mixin.py +4 -5
- edc_consent/model_mixins/requires_consent_fields_model_mixin.py +2 -2
- edc_consent/utils.py +1 -1
- edc_crf/migrations/0001_initial.py +3 -2
- edc_crf/migrations/0009_alter_crfstatus_device_created_and_more.py +54 -0
- edc_dashboard/migrations/0001_initial.py +3 -2
- edc_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_dashboard/templatetags/edc_dashboard_extras.py +3 -2
- edc_data_manager/action_items.py +4 -6
- edc_data_manager/admin/actions.py +5 -5
- edc_data_manager/handlers/handlers.py +6 -7
- edc_data_manager/migrations/0001_initial.py +19 -19
- edc_data_manager/migrations/0025_edcpermissions.py +3 -2
- edc_data_manager/migrations/0040_alter_datadictionary_device_created_and_more.py +327 -0
- edc_data_manager/migrations/0041_alter_dataquery_dm_user_and_more.py +164 -0
- edc_data_manager/models/data_query.py +5 -5
- edc_data_manager/models/model_mixins.py +8 -8
- edc_data_manager/rule/rule_runner.py +4 -3
- edc_document_status/model_mixins.py +1 -1
- edc_egfr/egfr.py +11 -7
- edc_egfr/model_mixins/egfr_model_mixin.py +3 -7
- edc_export/admin/data_request_admin.py +2 -2
- edc_export/archive_exporter.py +4 -3
- edc_export/files_archiver.py +3 -2
- edc_export/migrations/0001_initial.py +26 -26
- edc_export/migrations/0004_auto_20190305_0123.py +25 -72
- edc_export/migrations/0013_edcpermissions.py +3 -2
- edc_export/migrations/0022_alter_datarequest_description_and_more.py +611 -0
- edc_export/migrations/0023_alter_datarequesthistory_archive_filename_and_more.py +29 -0
- edc_export/model_exporter/file_history_updater.py +10 -10
- edc_export/model_exporter/model_exporter.py +13 -14
- edc_export/model_exporter/object_history_helpers.py +2 -2
- edc_export/models/data_request_history.py +4 -4
- edc_export/utils.py +10 -15
- edc_facility/facility.py +10 -15
- edc_facility/import_holidays.py +13 -13
- edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +8 -7
- edc_facility/migrations/0016_alter_healthfacility_device_created_and_more.py +139 -0
- edc_facility/migrations/0017_alter_healthfacility_gps_and_more.py +54 -0
- edc_facility/model_mixins.py +5 -5
- edc_form_runners/form_runner.py +3 -5
- edc_form_runners/migrations/0001_initial.py +3 -2
- edc_form_runners/migrations/0005_alter_issue_device_created_and_more.py +49 -0
- edc_identifier/migrations/0001_squashed_0018_auto_20180128_1054.py +3 -3
- edc_identifier/migrations/0002_auto_20190305_0123.py +3 -6
- edc_identifier/migrations/0006_auto_20161127_2226.py +15 -15
- edc_identifier/migrations/0007_auto_20161204_2227.py +3 -3
- edc_identifier/migrations/0009_auto_20161221_2323.py +3 -5
- edc_identifier/migrations/0010_auto_20170112_0602.py +17 -17
- edc_identifier/migrations/0011_alter_identifiermodel_device_created_and_more.py +79 -0
- edc_identifier/model_mixins.py +1 -1
- edc_identifier/models.py +9 -9
- edc_identifier/simple_identifier.py +1 -3
- edc_identifier/subject_identifier.py +3 -2
- edc_lab/migrations/0001_initial.py +29 -29
- edc_lab/migrations/0008_auto_20170921_0719.py +3 -3
- edc_lab/migrations/0010_auto_20171127_1541.py +15 -15
- edc_lab/migrations/0012_auto_20180114_1438.py +3 -3
- edc_lab/migrations/0019_auto_20190305_0123.py +43 -127
- edc_lab/migrations/0036_alter_aliquot_comment_alter_aliquot_device_created_and_more.py +1139 -0
- edc_lab/migrations/0037_alter_historicalorder_order_datetime_and_more.py +31 -0
- edc_lab/model_mixins/aliquot/aliquot_identifier_model_mixin.py +2 -2
- edc_lab/model_mixins/aliquot/aliquot_model_mixin.py +2 -2
- edc_lab/model_mixins/panel_model_mixin.py +18 -7
- edc_lab/model_mixins/requisition/crf_with_requisition_model_mixin.py +2 -4
- edc_lab/model_mixins/requisition/requisition_model_mixin.py +7 -8
- edc_lab/model_mixins/requisition/requisition_verify_model_mixin.py +1 -1
- edc_lab/model_mixins/result/result_item_model_mixin.py +4 -4
- edc_lab/model_mixins/shipping/manifest_model_mixin.py +4 -5
- edc_lab/model_mixins/shipping/verify_model_mixin.py +4 -6
- edc_lab/models/box.py +1 -1
- edc_lab/models/box_item.py +6 -7
- edc_lab/models/manifest/manifest.py +1 -1
- edc_lab/models/manifest/manifest_item.py +6 -6
- edc_lab/models/manifest/shipper.py +3 -4
- edc_lab/models/order.py +6 -4
- edc_lab/models/panel.py +4 -4
- edc_lab/models/result.py +2 -2
- edc_lab/models/result_item.py +2 -2
- edc_lab_dashboard/migrations/0001_initial.py +3 -2
- edc_lab_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_lab_dashboard/views/action_views/receive_view.py +2 -2
- edc_lab_dashboard/views/action_views/verify_box_item_view.py +2 -2
- edc_lab_results/model_mixins/blood_result_model_mixin.py +7 -7
- edc_lab_results/model_mixins/fbg_model_mixin.py +3 -3
- edc_lab_results/model_mixins/glucose_model_mixin.py +3 -3
- edc_lab_results/model_mixins/hba1c_model_mixin.py +3 -3
- edc_label/migrations/0001_initial.py +3 -2
- edc_label/migrations/0007_alter_zpllabeltemplates_device_created_and_more.py +49 -0
- edc_list_data/list_model_maker.py +2 -2
- edc_list_data/load_list_data.py +11 -14
- edc_list_data/model_mixins.py +12 -4
- edc_list_data/preload_data.py +3 -3
- edc_listboard/migrations/0001_initial.py +3 -2
- edc_listboard/migrations/0007_alter_listboard_device_created_and_more.py +49 -0
- edc_locator/migrations/0001_initial.py +7 -7
- edc_locator/migrations/0018_auto_20190305_0123.py +5 -12
- edc_locator/migrations/0040_alter_historicalsubjectlocator_action_identifier_and_more.py +187 -0
- edc_locator/migrations/0041_alter_historicalsubjectlocator_report_datetime_and_more.py +27 -0
- edc_locator/model_mixins/locator_model_mixin.py +2 -2
- edc_locator/model_mixins/subject_contact_fields_mixin.py +1 -1
- edc_locator/modeladmin_mixins.py +5 -4
- edc_ltfu/model_mixins.py +7 -5
- edc_metadata/metadata_rules/decorators.py +1 -1
- edc_metadata/migrations/0002_auto_20161127_2226.py +5 -5
- edc_metadata/migrations/0005_auto_20170112_0602.py +5 -5
- edc_metadata/migrations/0011_auto_20190305_0123.py +5 -12
- edc_metadata/migrations/0031_alter_crfmetadata_device_created_and_more.py +120 -0
- edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +1 -1
- edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +1 -1
- edc_metadata/models/crf_metadata.py +5 -5
- edc_metadata/models/crf_metadata_model_mixin.py +4 -5
- edc_metadata/models/requisition_metadata.py +6 -6
- edc_metadata/views/refresh_metadata_actions_view.py +3 -3
- edc_model/models/address_mixin.py +6 -6
- edc_model/models/fields/initials_field.py +2 -1
- edc_model/models/historical_records.py +2 -9
- edc_model/models/url_model_mixin.py +2 -2
- edc_model/validators/date.py +7 -8
- edc_model_admin/list_filters/future_date_list_filter.py +3 -3
- edc_model_admin/list_filters/past_date_list_filter.py +3 -3
- edc_model_admin/mixins/model_admin_protect_pii_mixin.py +4 -5
- edc_model_fields/fields/other_charfield.py +2 -2
- edc_navbar/migrations/0004_auto_20220825_0451.py +3 -2
- edc_navbar/migrations/0009_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_notification/migrations/0001_initial.py +3 -3
- edc_notification/migrations/0004_auto_20190305_0123.py +3 -6
- edc_notification/migrations/0011_alter_notification_device_created_and_more.py +59 -0
- edc_notification/models/notification.py +1 -1
- edc_notification/notification/notification.py +12 -12
- edc_offstudy/migrations/0001_initial.py +4 -4
- edc_offstudy/migrations/0002_auto_20180921_0434.py +4 -4
- edc_offstudy/migrations/0005_auto_20190305_0123.py +5 -12
- edc_offstudy/migrations/0023_alter_historicalsubjectoffstudy_action_identifier_and_more.py +188 -0
- edc_offstudy/migrations/0024_alter_historicalsubjectoffstudy_offstudy_datetime_and_more.py +43 -0
- edc_offstudy/model_mixins/offstudy_model_mixin.py +3 -2
- edc_pdutils/df_exporters/csv_exporter.py +33 -37
- edc_pdutils/df_exporters/csv_model_exporter.py +2 -1
- edc_pdutils/migrations/0001_initial.py +8 -8
- edc_pharmacy/admin/prescription/rx_refill_admin.py +4 -3
- edc_pharmacy/admin/reports/stock_availability_admin.py +5 -6
- edc_pharmacy/migrations/0001_initial.py +64 -63
- edc_pharmacy/migrations/0015_auto_20220913_2139.py +26 -26
- edc_pharmacy/migrations/0024_allocation_assignment_containerunits_dispense_and_more.py +81 -86
- edc_pharmacy/migrations/0037_remove_historicalstock_confirmed_at_site_by_and_more.py +5 -5
- edc_pharmacy/migrations/0039_remove_dispense_registered_subject_and_more.py +7 -8
- edc_pharmacy/migrations/0049_remove_stocktransferconfirmation_stock_and_more.py +12 -12
- edc_pharmacy/migrations/0050_remove_stocktransferconfirmation2_location_and_more.py +5 -5
- edc_pharmacy/migrations/0051_alter_historicalstocktransferconfirmationitem_options_and_more.py +3 -4
- edc_pharmacy/migrations/0053_alter_location_managers_alter_historicalstock_lot_and_more.py +3 -3
- edc_pharmacy/migrations/0057_scanduplicates.py +3 -3
- edc_pharmacy/migrations/0060_alter_container_max_per_subject_and_more.py +13 -15
- edc_pharmacy/migrations/0068_stockout.py +2 -3
- edc_pharmacy/migrations/0076_historicalstockadjustment_stockadjustment.py +5 -5
- edc_pharmacy/migrations/0077_historicalstockadjustment_adjustment_datetime_and_more.py +3 -4
- edc_pharmacy/migrations/0081_historicalconfirmation_confirmation.py +8 -8
- edc_pharmacy/migrations/0084_confirmationatsiteitem_and_more.py +0 -2
- edc_pharmacy/migrations/0089_alter_allocation_allocated_by_and_more.py +3284 -0
- edc_pharmacy/migrations/0090_alter_allocation_allocation_datetime_and_more.py +227 -0
- edc_pharmacy/model_mixins/study_medication_refill_model_mixin.py +2 -2
- edc_pharmacy/models/medication/medication.py +3 -3
- edc_pharmacy/models/model_mixins.py +10 -11
- edc_pharmacy/models/prescription/rx.py +13 -12
- edc_pharmacy/models/prescription/rx_refill.py +0 -1
- edc_pharmacy/models/stock/allocation.py +3 -3
- edc_pharmacy/models/stock/confirmation.py +3 -3
- edc_pharmacy/models/stock/confirmation_at_site.py +3 -2
- edc_pharmacy/models/stock/confirmation_at_site_item.py +3 -4
- edc_pharmacy/models/stock/dispense.py +5 -6
- edc_pharmacy/models/stock/dispense_item.py +2 -2
- edc_pharmacy/models/stock/location.py +3 -4
- edc_pharmacy/models/stock/lot.py +6 -7
- edc_pharmacy/models/stock/order.py +1 -1
- edc_pharmacy/models/stock/receive.py +3 -3
- edc_pharmacy/models/stock/receive_item.py +4 -4
- edc_pharmacy/models/stock/repack_request.py +2 -2
- edc_pharmacy/models/stock/stock.py +12 -18
- edc_pharmacy/models/stock/stock_adjustment.py +4 -4
- edc_pharmacy/models/stock/stock_request.py +2 -2
- edc_pharmacy/models/stock/stock_request_item.py +2 -2
- edc_pharmacy/models/stock/stock_transfer.py +3 -3
- edc_pharmacy/models/stock/stock_transfer_item.py +2 -2
- edc_pharmacy/models/stock/storage_bin.py +3 -4
- edc_pharmacy/models/stock/storage_bin_item.py +2 -2
- edc_pharmacy/models/stock/supplier.py +3 -4
- edc_pharmacy/models/storage/box.py +2 -2
- edc_pharmacy/models/storage/items/container_model_mixin.py +3 -4
- edc_pharmacy/models/storage/items/pill_bottle_model_mixin.py +2 -2
- edc_pharmacy/models/storage/items/subject_pill_bottle.py +1 -1
- edc_pharmacy/models/storage/room.py +2 -2
- edc_pharmacy/models/storage/shelf.py +2 -2
- edc_pharmacy/models/storage/utils.py +1 -1
- edc_pharmacy/utils/allocate_stock.py +2 -3
- edc_pharmacy/utils/confirm_stock.py +2 -3
- edc_pharmacy/utils/confirm_stock_at_site.py +3 -4
- edc_pharmacy/utils/dispense.py +3 -4
- edc_pharmacy/utils/process_repack_request.py +4 -5
- edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -3
- edc_pharmacy/utils/transfer_stock.py +2 -3
- edc_pharmacy/views/add_to_storage_bin_view.py +2 -2
- edc_pharmacy/views/allocate_to_subject_view.py +2 -2
- edc_pharmacy/views/dispense_view.py +2 -2
- edc_pharmacy/views/move_to_storage_bin_view.py +2 -3
- edc_pharmacy/views/print_labels_view.py +2 -2
- edc_protocol/research_protocol_config.py +2 -3
- edc_protocol_incident/migrations/0001_initial.py +7 -7
- edc_protocol_incident/migrations/0001_squashed_0015_auto_20220927_0401.py +13 -13
- edc_protocol_incident/migrations/0005_protocolincident_historicalprotocolincident_and_more.py +7 -7
- edc_protocol_incident/migrations/0024_alter_actionsrequired_extra_value_and_more.py +625 -0
- edc_protocol_incident/migrations/0025_alter_historicalprotocoldeviationviolation_report_datetime_and_more.py +42 -0
- edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +18 -11
- edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +26 -11
- edc_pylabels/actions.py +3 -5
- edc_pylabels/migrations/0002_alter_label_options_label_created_and_more.py +3 -7
- edc_pylabels/migrations/0005_labelconfiguration_delete_label_and_more.py +3 -3
- edc_pylabels/migrations/0013_alter_labelconfiguration_device_created_and_more.py +49 -0
- edc_qareports/migrations/0001_initial.py +4 -5
- edc_qareports/migrations/0005_edcpermissions.py +3 -3
- edc_qareports/migrations/0006_qareportlog.py +2 -3
- edc_qareports/migrations/0019_alter_edcpermissions_device_created_and_more.py +102 -0
- edc_qareports/migrations/0020_alter_note_report_datetime_and_more.py +24 -0
- edc_qareports/model_mixins/note_model_mixin.py +7 -4
- edc_qareports/model_mixins/on_study_missing_values_model_mixin.py +4 -4
- edc_qareports/model_mixins/qa_report_model_mixin.py +2 -3
- edc_qareports/models/note.py +4 -4
- edc_qareports/models/qa_reports_log.py +2 -3
- edc_randomization/decorators.py +1 -1
- edc_randomization/migrations/0001_initial.py +3 -2
- edc_randomization/migrations/0002_historicalrandomizationlist.py +3 -2
- edc_randomization/migrations/0009_edcpermissions.py +3 -2
- edc_randomization/migrations/0014_alter_edcpermissions_device_created_and_more.py +141 -0
- edc_randomization/model_mixins.py +9 -9
- edc_randomization/utils.py +2 -2
- edc_refusal/migrations/0001_initial.py +4 -4
- edc_refusal/migrations/0002_historicalsubjectrefusal.py +4 -4
- edc_refusal/migrations/0012_alter_historicalsubjectrefusal_comment_and_more.py +122 -0
- edc_refusal/migrations/0013_alter_historicalsubjectrefusal_report_datetime_and_more.py +28 -0
- edc_refusal/model_mixins.py +3 -3
- edc_registration/migrations/0002_auto_20161127_2226.py +3 -4
- edc_registration/migrations/0005_auto_20170111_1809.py +4 -2
- edc_registration/migrations/0016_historicalregisteredsubject.py +3 -2
- edc_registration/migrations/0017_auto_20190305_0123.py +5 -12
- edc_registration/migrations/0033_alter_historicalregisteredsubject_additional_key_and_more.py +302 -0
- edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +2 -3
- edc_registration/models/registered_subject.py +27 -26
- edc_reportable/age_evaluator.py +4 -2
- edc_reportable/formula.py +5 -5
- edc_reportable/migrations/0001_initial.py +7 -7
- edc_reportable/migrations/0003_referencerangecollection_grade1_and_more.py +3 -3
- edc_reportable/migrations/0004_alter_referencerangecollection_grade3_and_more.py +5 -5
- edc_reportable/migrations/0006_alter_gradingdata_revision_and_more.py +5 -6
- edc_reportable/migrations/0007_alter_gradingdata_age_phrase_and_more.py +509 -0
- edc_reportable/models/normal_data.py +4 -5
- edc_reportable/models/reference_model_mixins.py +10 -11
- edc_reportable/models/reference_range_collection.py +12 -13
- edc_reportable/post_migrate_signals.py +1 -1
- edc_reportable/utils/convert_units.py +11 -45
- edc_reportable/utils/get_normal_data_or_raise.py +2 -2
- edc_reportable/utils/load_data.py +4 -4
- edc_reportable/utils/update_grading_data.py +5 -5
- edc_review_dashboard/migrations/0001_initial.py +3 -2
- edc_review_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_screening/age_evaluator.py +3 -3
- edc_screening/migrations/0001_initial.py +3 -2
- edc_screening/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_screening/model_mixins/eligibility_model_mixin.py +3 -4
- edc_screening/model_mixins/screening_fields_model_mixin.py +6 -8
- edc_search/model_mixins.py +2 -3
- edc_search/search_slug.py +9 -8
- edc_search/updater.py +2 -2
- edc_sites/migrations/0007_edcpermissions.py +3 -2
- edc_sites/migrations/0010_alter_edcpermissions_device_created_and_more.py +69 -0
- edc_sites/model_mixins/site_model_mixin.py +2 -2
- edc_sites/site.py +5 -5
- edc_sites/system_checks.py +1 -1
- edc_subject_dashboard/migrations/0001_initial.py +3 -2
- edc_subject_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
- edc_subject_dashboard/requisition_report.py +6 -4
- edc_subject_dashboard/requisition_verifier.py +6 -6
- edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +2 -2
- edc_subject_dashboard/view_mixins/subject_visit_view_mixin.py +7 -8
- edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +3 -2
- edc_subject_dashboard/view_utils/timepoint_status_button.py +2 -2
- edc_timepoint/model_mixins.py +22 -20
- edc_transfer/model_mixins.py +4 -4
- edc_transfer/modeladmin_mixins.py +1 -1
- edc_unblinding/migrations/0001_initial.py +13 -13
- edc_unblinding/migrations/0014_alter_historicalunblindingrequest_action_identifier_and_more.py +291 -0
- edc_unblinding/migrations/0015_alter_historicalunblindingrequest_report_datetime_and_more.py +45 -0
- edc_unblinding/models/unblinding_request.py +2 -2
- edc_unblinding/models/unblinding_review.py +3 -3
- edc_utils/age.py +10 -16
- edc_visit_schedule/migrations/0001_initial.py +3 -3
- edc_visit_schedule/migrations/0002_auto_20190305_0123.py +3 -6
- edc_visit_schedule/migrations/0003_historicalvisitschedule_visitschedule.py +5 -4
- edc_visit_schedule/migrations/0015_historicalonschedule_offschedule_onschedule.py +10 -10
- edc_visit_schedule/migrations/0019_alter_historicalonschedule_device_created_and_more.py +229 -0
- edc_visit_schedule/migrations/0020_alter_historicalonschedule_onschedule_datetime_and_more.py +65 -0
- edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +5 -4
- edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +5 -4
- edc_visit_schedule/model_mixins/visit_schedule/visit_code_fields_model_mixin.py +1 -1
- edc_visit_schedule/models/subject_schedule_history.py +6 -6
- edc_visit_schedule/schedule/visit_collection.py +1 -1
- edc_visit_schedule/subject_schedule.py +5 -4
- edc_visit_schedule/view_mixins.py +2 -3
- edc_visit_schedule/visit/visit.py +3 -2
- edc_visit_tracking/migrations/0004_subjectvisit_subjectvisitmissedreasons_extra_value_and_more.py +13 -13
- edc_visit_tracking/migrations/0009_alter_historicalsubjectvisit_comments_and_more.py +450 -0
- edc_visit_tracking/migrations/0010_alter_historicalsubjectvisit_report_datetime_and_more.py +68 -0
- edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +3 -3
- edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +2 -2
- edc_visit_tracking/model_mixins/requisitions/visit_tracking_requisition_model_mixin.py +2 -2
- edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +2 -2
- edc_visit_tracking/model_mixins/visit_model_mixin/caretaker_fields_mixin.py +2 -3
- edc_visit_tracking/model_mixins/visit_model_mixin/previous_visit_model_mixin.py +1 -1
- edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_fields_mixin.py +8 -11
- edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +1 -1
- edc_visit_tracking/models/signals.py +1 -1
- edc_visit_tracking/models/subject_visit.py +1 -1
- edc_vitals/calculators/bmi.py +7 -5
- edc_vitals/utils.py +1 -1
- {clinicedc-2.0.6.dist-info → clinicedc-2.0.7.dist-info}/WHEEL +0 -0
- {clinicedc-2.0.6.dist-info → clinicedc-2.0.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import django.utils.timezone
|
|
1
2
|
from django.db import models
|
|
2
3
|
|
|
3
4
|
from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
|
|
4
|
-
from edc_utils import get_utcnow
|
|
5
5
|
|
|
6
6
|
from .locator_methods_model_mixin import LocatorMethodsModelMixin
|
|
7
7
|
from .subject_contact_fields_mixin import SubjectContactFieldsMixin
|
|
@@ -30,7 +30,7 @@ class LocatorModelMixin(
|
|
|
30
30
|
This model is used in ListboardViews.
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
report_datetime = models.DateTimeField(default=
|
|
33
|
+
report_datetime = models.DateTimeField(default=django.utils.timezone.now)
|
|
34
34
|
|
|
35
35
|
objects = LocatorManager()
|
|
36
36
|
|
edc_locator/modeladmin_mixins.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
from django.template.loader import render_to_string
|
|
3
|
+
from django.utils import timezone
|
|
3
4
|
from django_audit_fields.admin import audit_fieldset_tuple
|
|
4
5
|
|
|
5
6
|
from edc_consent import site_consents
|
|
6
7
|
from edc_constants.constants import NO, YES
|
|
7
8
|
from edc_model_admin.mixins import ModelAdminProtectPiiMixin
|
|
8
9
|
from edc_sites import site_sites
|
|
9
|
-
from edc_utils import age
|
|
10
|
+
from edc_utils.age import age
|
|
10
11
|
|
|
11
12
|
from .fieldsets import (
|
|
12
13
|
indirect_contacts_fieldset,
|
|
@@ -19,7 +20,7 @@ from .forms import SubjectLocatorForm
|
|
|
19
20
|
class SubjectLocatorModelAdminMixin(ModelAdminProtectPiiMixin):
|
|
20
21
|
form = SubjectLocatorForm
|
|
21
22
|
|
|
22
|
-
extra_pii_attrs: list[str] =
|
|
23
|
+
extra_pii_attrs: list[str] = ("contacts",)
|
|
23
24
|
|
|
24
25
|
fieldsets = (
|
|
25
26
|
(None, {"fields": ("subject_identifier",)}),
|
|
@@ -29,7 +30,7 @@ class SubjectLocatorModelAdminMixin(ModelAdminProtectPiiMixin):
|
|
|
29
30
|
audit_fieldset_tuple,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
|
-
radio_fields = {
|
|
33
|
+
radio_fields = { # noqa: RUF012
|
|
33
34
|
"may_visit_home": admin.VERTICAL,
|
|
34
35
|
"may_call": admin.VERTICAL,
|
|
35
36
|
"may_sms": admin.VERTICAL,
|
|
@@ -74,7 +75,7 @@ class SubjectLocatorModelAdminMixin(ModelAdminProtectPiiMixin):
|
|
|
74
75
|
context = dict(
|
|
75
76
|
subject_identifier=obj.subject_identifier,
|
|
76
77
|
gender=consent.gender.upper(),
|
|
77
|
-
age_in_years=age(born=consent.dob, reference_dt=
|
|
78
|
+
age_in_years=age(born=consent.dob, reference_dt=timezone.now()).years,
|
|
78
79
|
initials=consent.initials,
|
|
79
80
|
)
|
|
80
81
|
return render_to_string("edc_locator/changelist_locator_subject.html", context=context)
|
edc_ltfu/model_mixins.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from django.core.validators import MinValueValidator
|
|
2
2
|
from django.db import models
|
|
3
|
+
from django.utils import timezone
|
|
3
4
|
|
|
4
5
|
from edc_constants.choices import YES_NO
|
|
5
6
|
from edc_model import models as edc_models
|
|
6
7
|
from edc_protocol.validators import date_not_before_study_start
|
|
7
|
-
from edc_utils.date import get_utcnow
|
|
8
8
|
|
|
9
9
|
from .choices import LTFU_CHOICES
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ from .choices import LTFU_CHOICES
|
|
|
12
12
|
class LtfuModelMixin(models.Model):
|
|
13
13
|
report_datetime = models.DateTimeField(
|
|
14
14
|
verbose_name="Report Date and Time",
|
|
15
|
-
default=
|
|
15
|
+
default=timezone.now,
|
|
16
16
|
validators=[date_not_before_study_start],
|
|
17
17
|
)
|
|
18
18
|
|
|
@@ -33,7 +33,7 @@ class LtfuModelMixin(models.Model):
|
|
|
33
33
|
|
|
34
34
|
ltfu_date = models.DateField(
|
|
35
35
|
verbose_name="Date participant considered lost to follow up",
|
|
36
|
-
default=
|
|
36
|
+
default=timezone.now,
|
|
37
37
|
null=True,
|
|
38
38
|
blank=False,
|
|
39
39
|
)
|
|
@@ -42,12 +42,12 @@ class LtfuModelMixin(models.Model):
|
|
|
42
42
|
verbose_name="Was contact by phone attempted",
|
|
43
43
|
max_length=15,
|
|
44
44
|
choices=YES_NO,
|
|
45
|
-
|
|
45
|
+
default="",
|
|
46
46
|
blank=False,
|
|
47
47
|
)
|
|
48
48
|
phone_attempts = models.IntegerField(
|
|
49
49
|
verbose_name=(
|
|
50
|
-
"If YES, how many attempts were made to contact the participant by phone"
|
|
50
|
+
"If YES, how many attempts were made to contact the participant by phone"
|
|
51
51
|
),
|
|
52
52
|
validators=[MinValueValidator(0)],
|
|
53
53
|
default=0,
|
|
@@ -60,6 +60,7 @@ class LtfuModelMixin(models.Model):
|
|
|
60
60
|
home_visit_detail = models.TextField(
|
|
61
61
|
verbose_name="If YES, provide any further details of the home visit",
|
|
62
62
|
blank=True,
|
|
63
|
+
default="",
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
ltfu_category = models.CharField(
|
|
@@ -76,6 +77,7 @@ class LtfuModelMixin(models.Model):
|
|
|
76
77
|
"circumstances that led to this decision."
|
|
77
78
|
),
|
|
78
79
|
blank=True,
|
|
80
|
+
default="",
|
|
79
81
|
)
|
|
80
82
|
|
|
81
83
|
class Meta:
|
|
@@ -4,7 +4,7 @@ from __future__ import unicode_literals
|
|
|
4
4
|
|
|
5
5
|
from django.db import migrations, models
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import django.utils.timezone
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class Migration(migrations.Migration):
|
|
@@ -14,21 +14,21 @@ class Migration(migrations.Migration):
|
|
|
14
14
|
migrations.AlterField(
|
|
15
15
|
model_name="crfmetadata",
|
|
16
16
|
name="created",
|
|
17
|
-
field=models.DateTimeField(default=
|
|
17
|
+
field=models.DateTimeField(default=django.utils.timezone.now, editable=False),
|
|
18
18
|
),
|
|
19
19
|
migrations.AlterField(
|
|
20
20
|
model_name="crfmetadata",
|
|
21
21
|
name="modified",
|
|
22
|
-
field=models.DateTimeField(default=
|
|
22
|
+
field=models.DateTimeField(default=django.utils.timezone.now, editable=False),
|
|
23
23
|
),
|
|
24
24
|
migrations.AlterField(
|
|
25
25
|
model_name="requisitionmetadata",
|
|
26
26
|
name="created",
|
|
27
|
-
field=models.DateTimeField(default=
|
|
27
|
+
field=models.DateTimeField(default=django.utils.timezone.now, editable=False),
|
|
28
28
|
),
|
|
29
29
|
migrations.AlterField(
|
|
30
30
|
model_name="requisitionmetadata",
|
|
31
31
|
name="modified",
|
|
32
|
-
field=models.DateTimeField(default=
|
|
32
|
+
field=models.DateTimeField(default=django.utils.timezone.now, editable=False),
|
|
33
33
|
),
|
|
34
34
|
]
|
|
@@ -6,7 +6,7 @@ from django.db import migrations, models
|
|
|
6
6
|
|
|
7
7
|
import edc_model_fields.fields.hostname_modification_field
|
|
8
8
|
import edc_model_fields.fields.userfield
|
|
9
|
-
import
|
|
9
|
+
import django.utils.timezone
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Migration(migrations.Migration):
|
|
@@ -16,7 +16,7 @@ class Migration(migrations.Migration):
|
|
|
16
16
|
migrations.AlterField(
|
|
17
17
|
model_name="crfmetadata",
|
|
18
18
|
name="created",
|
|
19
|
-
field=models.DateTimeField(blank=True, default=
|
|
19
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
20
20
|
),
|
|
21
21
|
migrations.AlterField(
|
|
22
22
|
model_name="crfmetadata",
|
|
@@ -40,7 +40,7 @@ class Migration(migrations.Migration):
|
|
|
40
40
|
migrations.AlterField(
|
|
41
41
|
model_name="crfmetadata",
|
|
42
42
|
name="modified",
|
|
43
|
-
field=models.DateTimeField(blank=True, default=
|
|
43
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
44
44
|
),
|
|
45
45
|
migrations.AlterField(
|
|
46
46
|
model_name="crfmetadata",
|
|
@@ -59,7 +59,7 @@ class Migration(migrations.Migration):
|
|
|
59
59
|
migrations.AlterField(
|
|
60
60
|
model_name="requisitionmetadata",
|
|
61
61
|
name="created",
|
|
62
|
-
field=models.DateTimeField(blank=True, default=
|
|
62
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
63
63
|
),
|
|
64
64
|
migrations.AlterField(
|
|
65
65
|
model_name="requisitionmetadata",
|
|
@@ -83,7 +83,7 @@ class Migration(migrations.Migration):
|
|
|
83
83
|
migrations.AlterField(
|
|
84
84
|
model_name="requisitionmetadata",
|
|
85
85
|
name="modified",
|
|
86
|
-
field=models.DateTimeField(blank=True, default=
|
|
86
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
87
87
|
),
|
|
88
88
|
migrations.AlterField(
|
|
89
89
|
model_name="requisitionmetadata",
|
|
@@ -4,6 +4,7 @@ import django_audit_fields.fields.hostname_modification_field
|
|
|
4
4
|
import django_audit_fields.fields.userfield
|
|
5
5
|
import django_audit_fields.models.audit_model_mixin
|
|
6
6
|
from django.db import migrations, models
|
|
7
|
+
import django.utils.timezone
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class Migration(migrations.Migration):
|
|
@@ -13,9 +14,7 @@ class Migration(migrations.Migration):
|
|
|
13
14
|
migrations.AlterField(
|
|
14
15
|
model_name="crfmetadata",
|
|
15
16
|
name="created",
|
|
16
|
-
field=models.DateTimeField(
|
|
17
|
-
blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
|
|
18
|
-
),
|
|
17
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
19
18
|
),
|
|
20
19
|
migrations.AlterField(
|
|
21
20
|
model_name="crfmetadata",
|
|
@@ -29,9 +28,7 @@ class Migration(migrations.Migration):
|
|
|
29
28
|
migrations.AlterField(
|
|
30
29
|
model_name="crfmetadata",
|
|
31
30
|
name="modified",
|
|
32
|
-
field=models.DateTimeField(
|
|
33
|
-
blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
|
|
34
|
-
),
|
|
31
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
35
32
|
),
|
|
36
33
|
migrations.AlterField(
|
|
37
34
|
model_name="crfmetadata",
|
|
@@ -56,9 +53,7 @@ class Migration(migrations.Migration):
|
|
|
56
53
|
migrations.AlterField(
|
|
57
54
|
model_name="requisitionmetadata",
|
|
58
55
|
name="created",
|
|
59
|
-
field=models.DateTimeField(
|
|
60
|
-
blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
|
|
61
|
-
),
|
|
56
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
62
57
|
),
|
|
63
58
|
migrations.AlterField(
|
|
64
59
|
model_name="requisitionmetadata",
|
|
@@ -72,9 +67,7 @@ class Migration(migrations.Migration):
|
|
|
72
67
|
migrations.AlterField(
|
|
73
68
|
model_name="requisitionmetadata",
|
|
74
69
|
name="modified",
|
|
75
|
-
field=models.DateTimeField(
|
|
76
|
-
blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
|
|
77
|
-
),
|
|
70
|
+
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
78
71
|
),
|
|
79
72
|
migrations.AlterField(
|
|
80
73
|
model_name="requisitionmetadata",
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-17 16:53
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("edc_metadata", "0030_alter_crfmetadata_revision_and_more"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="crfmetadata",
|
|
15
|
+
name="device_created",
|
|
16
|
+
field=models.CharField(
|
|
17
|
+
blank=True, default="", max_length=10, verbose_name="Device created"
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name="crfmetadata",
|
|
22
|
+
name="device_modified",
|
|
23
|
+
field=models.CharField(
|
|
24
|
+
blank=True, default="", max_length=10, verbose_name="Device modified"
|
|
25
|
+
),
|
|
26
|
+
),
|
|
27
|
+
migrations.AlterField(
|
|
28
|
+
model_name="crfmetadata",
|
|
29
|
+
name="document_name",
|
|
30
|
+
field=models.CharField(default="", max_length=250, verbose_name="Document"),
|
|
31
|
+
),
|
|
32
|
+
migrations.AlterField(
|
|
33
|
+
model_name="crfmetadata",
|
|
34
|
+
name="document_user",
|
|
35
|
+
field=models.CharField(default="", max_length=50, verbose_name="User"),
|
|
36
|
+
),
|
|
37
|
+
migrations.AlterField(
|
|
38
|
+
model_name="crfmetadata",
|
|
39
|
+
name="entry_comment",
|
|
40
|
+
field=models.TextField(blank=True, default="", max_length=250),
|
|
41
|
+
),
|
|
42
|
+
migrations.AlterField(
|
|
43
|
+
model_name="crfmetadata",
|
|
44
|
+
name="locale_created",
|
|
45
|
+
field=models.CharField(
|
|
46
|
+
blank=True,
|
|
47
|
+
default="",
|
|
48
|
+
help_text="Auto-updated by Modeladmin",
|
|
49
|
+
max_length=10,
|
|
50
|
+
verbose_name="Locale created",
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
migrations.AlterField(
|
|
54
|
+
model_name="crfmetadata",
|
|
55
|
+
name="locale_modified",
|
|
56
|
+
field=models.CharField(
|
|
57
|
+
blank=True,
|
|
58
|
+
default="",
|
|
59
|
+
help_text="Auto-updated by Modeladmin",
|
|
60
|
+
max_length=10,
|
|
61
|
+
verbose_name="Locale modified",
|
|
62
|
+
),
|
|
63
|
+
),
|
|
64
|
+
migrations.AlterField(
|
|
65
|
+
model_name="requisitionmetadata",
|
|
66
|
+
name="device_created",
|
|
67
|
+
field=models.CharField(
|
|
68
|
+
blank=True, default="", max_length=10, verbose_name="Device created"
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
migrations.AlterField(
|
|
72
|
+
model_name="requisitionmetadata",
|
|
73
|
+
name="device_modified",
|
|
74
|
+
field=models.CharField(
|
|
75
|
+
blank=True, default="", max_length=10, verbose_name="Device modified"
|
|
76
|
+
),
|
|
77
|
+
),
|
|
78
|
+
migrations.AlterField(
|
|
79
|
+
model_name="requisitionmetadata",
|
|
80
|
+
name="document_name",
|
|
81
|
+
field=models.CharField(default="", max_length=250, verbose_name="Document"),
|
|
82
|
+
),
|
|
83
|
+
migrations.AlterField(
|
|
84
|
+
model_name="requisitionmetadata",
|
|
85
|
+
name="document_user",
|
|
86
|
+
field=models.CharField(default="", max_length=50, verbose_name="User"),
|
|
87
|
+
),
|
|
88
|
+
migrations.AlterField(
|
|
89
|
+
model_name="requisitionmetadata",
|
|
90
|
+
name="entry_comment",
|
|
91
|
+
field=models.TextField(blank=True, default="", max_length=250),
|
|
92
|
+
),
|
|
93
|
+
migrations.AlterField(
|
|
94
|
+
model_name="requisitionmetadata",
|
|
95
|
+
name="locale_created",
|
|
96
|
+
field=models.CharField(
|
|
97
|
+
blank=True,
|
|
98
|
+
default="",
|
|
99
|
+
help_text="Auto-updated by Modeladmin",
|
|
100
|
+
max_length=10,
|
|
101
|
+
verbose_name="Locale created",
|
|
102
|
+
),
|
|
103
|
+
),
|
|
104
|
+
migrations.AlterField(
|
|
105
|
+
model_name="requisitionmetadata",
|
|
106
|
+
name="locale_modified",
|
|
107
|
+
field=models.CharField(
|
|
108
|
+
blank=True,
|
|
109
|
+
default="",
|
|
110
|
+
help_text="Auto-updated by Modeladmin",
|
|
111
|
+
max_length=10,
|
|
112
|
+
verbose_name="Locale modified",
|
|
113
|
+
),
|
|
114
|
+
),
|
|
115
|
+
migrations.AlterField(
|
|
116
|
+
model_name="requisitionmetadata",
|
|
117
|
+
name="panel_name",
|
|
118
|
+
field=models.CharField(default="", max_length=50),
|
|
119
|
+
),
|
|
120
|
+
]
|
|
@@ -59,7 +59,7 @@ class UpdatesCrfMetadataModelMixin(UpdatesMetadataModelMixin):
|
|
|
59
59
|
crfs = self.metadata_visit_object.crfs_unscheduled.forms + crfs_prn.forms
|
|
60
60
|
else:
|
|
61
61
|
crfs = self.metadata_visit_object.crfs.forms + crfs_prn.forms
|
|
62
|
-
crf =
|
|
62
|
+
crf = next(c for c in crfs if c.model == self._meta.label_lower)
|
|
63
63
|
return REQUIRED if crf.required else NOT_REQUIRED
|
|
64
64
|
|
|
65
65
|
class Meta:
|
|
@@ -64,7 +64,7 @@ class UpdatesRequisitionMetadataModelMixin(UpdatesMetadataModelMixin):
|
|
|
64
64
|
requisitions = (
|
|
65
65
|
self.metadata_visit_object.requisitions.forms + requisitions_prn.forms
|
|
66
66
|
)
|
|
67
|
-
requisition =
|
|
67
|
+
requisition = next(r for r in requisitions if r.panel.name == self.panel.name)
|
|
68
68
|
return REQUIRED if requisition.required else NOT_REQUIRED
|
|
69
69
|
|
|
70
70
|
@property
|
|
@@ -29,7 +29,7 @@ class CrfMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
# noinspection PyTypeHints
|
|
32
|
-
natural_key.dependencies =
|
|
32
|
+
natural_key.dependencies = ("sites.Site",)
|
|
33
33
|
|
|
34
34
|
@property
|
|
35
35
|
def verbose_name(self) -> str:
|
|
@@ -42,8 +42,8 @@ class CrfMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
42
42
|
class Meta(CrfMetadataModelMixin.Meta, BaseUuidModel.Meta):
|
|
43
43
|
verbose_name = "Crf collection status"
|
|
44
44
|
verbose_name_plural = "Crf collection status"
|
|
45
|
-
unique_together =
|
|
46
|
-
constraints =
|
|
45
|
+
unique_together = ()
|
|
46
|
+
constraints = (
|
|
47
47
|
UniqueConstraint(
|
|
48
48
|
fields=[
|
|
49
49
|
"subject_identifier",
|
|
@@ -54,8 +54,8 @@ class CrfMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
54
54
|
"model",
|
|
55
55
|
],
|
|
56
56
|
name="%(app_label)s_%(class)s_subject_iden_visit_uniq",
|
|
57
|
-
)
|
|
58
|
-
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
59
|
indexes = (
|
|
60
60
|
*CrfMetadataModelMixin.Meta.indexes,
|
|
61
61
|
*BaseUuidModel.Meta.indexes,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import contextlib
|
|
3
4
|
from typing import TYPE_CHECKING, Any
|
|
4
5
|
|
|
5
6
|
from django.apps import apps as django_apps
|
|
@@ -38,7 +39,7 @@ class CrfMetadataModelMixin(
|
|
|
38
39
|
|
|
39
40
|
model = models.CharField(max_length=50)
|
|
40
41
|
|
|
41
|
-
document_name = models.CharField(verbose_name=_("Document"), max_length=250,
|
|
42
|
+
document_name = models.CharField(verbose_name=_("Document"), max_length=250, default="")
|
|
42
43
|
|
|
43
44
|
show_order = models.IntegerField() # must always be provided!
|
|
44
45
|
|
|
@@ -54,7 +55,7 @@ class CrfMetadataModelMixin(
|
|
|
54
55
|
|
|
55
56
|
fill_datetime = models.DateTimeField(null=True, blank=True)
|
|
56
57
|
|
|
57
|
-
document_user = models.CharField(verbose_name=_("User"), max_length=50,
|
|
58
|
+
document_user = models.CharField(verbose_name=_("User"), max_length=50, default="")
|
|
58
59
|
|
|
59
60
|
def natural_key(self):
|
|
60
61
|
return (
|
|
@@ -92,10 +93,8 @@ class CrfMetadataModelMixin(
|
|
|
92
93
|
def model_instance(self: Any) -> Any:
|
|
93
94
|
"""Returns the CRF/Requisition model instance or None"""
|
|
94
95
|
instance = None
|
|
95
|
-
|
|
96
|
+
with contextlib.suppress(ObjectDoesNotExist):
|
|
96
97
|
instance = self.model_cls.objects.get(**self.model_instance_query_opts())
|
|
97
|
-
except ObjectDoesNotExist:
|
|
98
|
-
pass
|
|
99
98
|
return instance
|
|
100
99
|
|
|
101
100
|
def refresh_entry_status(self) -> str:
|
|
@@ -10,7 +10,7 @@ from .crf_metadata_model_mixin import CrfMetadataModelMixin
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class RequisitionMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
13
|
-
panel_name = models.CharField(max_length=50,
|
|
13
|
+
panel_name = models.CharField(max_length=50, default="")
|
|
14
14
|
|
|
15
15
|
objects = RequisitionMetadataManager()
|
|
16
16
|
|
|
@@ -26,7 +26,7 @@ class RequisitionMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
26
26
|
|
|
27
27
|
@property
|
|
28
28
|
def verbose_name(self) -> str:
|
|
29
|
-
from edc_lab.site_labs import site_labs
|
|
29
|
+
from edc_lab.site_labs import site_labs # noqa: PLC0415
|
|
30
30
|
|
|
31
31
|
return site_labs.panel_names.get(self.panel_name) or self.panel_name
|
|
32
32
|
|
|
@@ -42,7 +42,7 @@ class RequisitionMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
# noinspection PyTypeHints
|
|
45
|
-
natural_key.dependencies =
|
|
45
|
+
natural_key.dependencies = ("sites.Site",) # type: ignore
|
|
46
46
|
|
|
47
47
|
def model_instance_query_opts(self) -> dict:
|
|
48
48
|
opts = super().model_instance_query_opts()
|
|
@@ -71,7 +71,7 @@ class RequisitionMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
71
71
|
app_label = "edc_metadata"
|
|
72
72
|
verbose_name = "Requisition collection status"
|
|
73
73
|
verbose_name_plural = "Requisition collection status"
|
|
74
|
-
constraints =
|
|
74
|
+
constraints = (
|
|
75
75
|
UniqueConstraint(
|
|
76
76
|
fields=[
|
|
77
77
|
"subject_identifier",
|
|
@@ -83,8 +83,8 @@ class RequisitionMetadata(CrfMetadataModelMixin, BaseUuidModel):
|
|
|
83
83
|
"panel_name",
|
|
84
84
|
],
|
|
85
85
|
name="%(app_label)s_%(class)s_subject_iden_visit_uniq",
|
|
86
|
-
)
|
|
87
|
-
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
88
|
indexes = (
|
|
89
89
|
*CrfMetadataModelMixin.Meta.indexes,
|
|
90
90
|
*BaseUuidModel.Meta.indexes,
|
|
@@ -3,11 +3,11 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
|
|
3
3
|
from django.contrib.messages import SUCCESS
|
|
4
4
|
from django.http.response import HttpResponseRedirect
|
|
5
5
|
from django.urls import reverse
|
|
6
|
+
from django.utils import timezone
|
|
6
7
|
from django.views import View
|
|
7
8
|
|
|
8
9
|
from edc_appointment.utils import update_appt_status_for_timepoint
|
|
9
10
|
from edc_dashboard.url_names import url_names
|
|
10
|
-
from edc_utils import get_utcnow
|
|
11
11
|
from edc_utils.round_up import round_half_away_from_zero
|
|
12
12
|
from edc_visit_tracking.utils import get_related_visit_model_cls
|
|
13
13
|
|
|
@@ -34,7 +34,7 @@ class RefreshMetadataActionsView(LoginRequiredMixin, View):
|
|
|
34
34
|
return related_visit
|
|
35
35
|
|
|
36
36
|
def get(self, request, *args, **kwargs):
|
|
37
|
-
dte1 =
|
|
37
|
+
dte1 = timezone.now()
|
|
38
38
|
related_visit = self.refresh_metadata_for_timepoint(**kwargs)
|
|
39
39
|
url_name = url_names.get("subject_dashboard_url")
|
|
40
40
|
args = (
|
|
@@ -47,7 +47,7 @@ class RefreshMetadataActionsView(LoginRequiredMixin, View):
|
|
|
47
47
|
SUCCESS,
|
|
48
48
|
f"The data collection schedule for {related_visit.visit_code}."
|
|
49
49
|
f"{related_visit.visit_code_sequence} has been refreshed "
|
|
50
|
-
f"({round_half_away_from_zero((
|
|
50
|
+
f"({round_half_away_from_zero((timezone.now() - dte1).microseconds / 1000000, 2)} "
|
|
51
51
|
"seconds)",
|
|
52
52
|
)
|
|
53
53
|
return HttpResponseRedirect(url)
|
|
@@ -2,7 +2,7 @@ from django.db import models
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class AddressMixin(models.Model):
|
|
5
|
-
contact_name = models.CharField(max_length=50,
|
|
5
|
+
contact_name = models.CharField(max_length=50, default="", blank=True)
|
|
6
6
|
|
|
7
7
|
address = models.CharField(verbose_name="Address", max_length=50)
|
|
8
8
|
|
|
@@ -11,18 +11,18 @@ class AddressMixin(models.Model):
|
|
|
11
11
|
city = models.CharField(max_length=50)
|
|
12
12
|
|
|
13
13
|
state = models.CharField(
|
|
14
|
-
verbose_name="State or Province",
|
|
14
|
+
verbose_name="State or Province", default="", blank=True, max_length=50
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
country = models.CharField(max_length=50)
|
|
18
18
|
|
|
19
|
-
telephone = models.CharField(
|
|
19
|
+
telephone = models.CharField(default="", blank=True, max_length=50)
|
|
20
20
|
|
|
21
|
-
mobile = models.CharField(
|
|
21
|
+
mobile = models.CharField(default="", blank=True, max_length=50)
|
|
22
22
|
|
|
23
|
-
fax = models.CharField(
|
|
23
|
+
fax = models.CharField(default="", blank=True, max_length=50)
|
|
24
24
|
|
|
25
|
-
email = models.EmailField(
|
|
25
|
+
email = models.EmailField(default="", blank=True, max_length=50)
|
|
26
26
|
|
|
27
27
|
class Meta:
|
|
28
28
|
abstract = True
|
|
@@ -12,6 +12,7 @@ class InitialsField(CharField):
|
|
|
12
12
|
kwargs.setdefault("editable", True)
|
|
13
13
|
kwargs.setdefault("verbose_name", _("Initials"))
|
|
14
14
|
kwargs.setdefault("max_length", 3)
|
|
15
|
+
kwargs.setdefault("default", "")
|
|
15
16
|
kwargs.setdefault("help_text", _("Type 2-3 letters, all in uppercase and no spaces"))
|
|
16
17
|
CharField.__init__(self, *args, **kwargs)
|
|
17
18
|
|
|
@@ -31,4 +32,4 @@ class InitialsField(CharField):
|
|
|
31
32
|
},
|
|
32
33
|
}
|
|
33
34
|
defaults.update(kwargs)
|
|
34
|
-
return super(
|
|
35
|
+
return super().formfield(**defaults)
|
|
@@ -16,10 +16,7 @@ class SerializableModel(models.Model):
|
|
|
16
16
|
return (self.history_id,)
|
|
17
17
|
|
|
18
18
|
def related_visit_model_attr(self):
|
|
19
|
-
|
|
20
|
-
return self.history_object.related_visit_model_attr()
|
|
21
|
-
except AttributeError:
|
|
22
|
-
raise
|
|
19
|
+
return self.history_object.related_visit_model_attr()
|
|
23
20
|
|
|
24
21
|
@property
|
|
25
22
|
def related_visit(self):
|
|
@@ -61,10 +58,6 @@ class HistoricalRecords(SimpleHistoricalRecords):
|
|
|
61
58
|
super().__init__(**kwargs)
|
|
62
59
|
|
|
63
60
|
def contribute_to_class(self, cls, name):
|
|
64
|
-
|
|
65
|
-
cls.related_visit_model_attr
|
|
66
|
-
except AttributeError:
|
|
67
|
-
pass
|
|
68
|
-
else:
|
|
61
|
+
if getattr(cls, "related_visit_model_attr", None):
|
|
69
62
|
self.model_cls = SerializableCrfModel
|
|
70
63
|
return super().contribute_to_class(cls, name)
|
|
@@ -5,7 +5,7 @@ from django.urls import reverse
|
|
|
5
5
|
from django.urls.exceptions import NoReverseMatch
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class UrlModelMixinNoReverseMatch(Exception):
|
|
8
|
+
class UrlModelMixinNoReverseMatch(Exception): # noqa: N818
|
|
9
9
|
pass
|
|
10
10
|
|
|
11
11
|
|
|
@@ -23,7 +23,7 @@ class UrlModelMixin(models.Model):
|
|
|
23
23
|
f"Tried {self.admin_url_name}. Got {e}. "
|
|
24
24
|
"Check urls and confirm app is in INSTALLED_APPS. If running tests, "
|
|
25
25
|
"you may need to set `use_test_urls=True`."
|
|
26
|
-
)
|
|
26
|
+
) from e
|
|
27
27
|
return absolute_url
|
|
28
28
|
|
|
29
29
|
def get_changelist_url(self, search_term=None) -> str:
|