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
edc_model/validators/date.py
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
from datetime import date, datetime, timedelta
|
|
2
2
|
|
|
3
3
|
from django.core.exceptions import ValidationError
|
|
4
|
-
|
|
5
|
-
from edc_utils import get_utcnow
|
|
4
|
+
from django.utils import timezone
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
def datetime_not_future(utc_datetime: datetime) -> None:
|
|
9
8
|
time_error = timedelta(minutes=10)
|
|
10
|
-
if utc_datetime >
|
|
9
|
+
if utc_datetime > timezone.now() + time_error:
|
|
11
10
|
raise ValidationError("Cannot be a future date/time")
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
def date_not_future(value: date) -> None:
|
|
15
|
-
if value >
|
|
14
|
+
if value > timezone.now().date():
|
|
16
15
|
raise ValidationError("Cannot be a future date")
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
def date_is_past(value: date) -> None:
|
|
20
|
-
if value >
|
|
19
|
+
if value > timezone.now().date():
|
|
21
20
|
raise ValidationError("Expected a past date")
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
def date_is_not_now(value: date) -> None:
|
|
25
|
-
if value ==
|
|
24
|
+
if value == timezone.now().date():
|
|
26
25
|
raise ValidationError("Cannot be today")
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
def datetime_is_future(utc_datetime: datetime) -> None:
|
|
30
29
|
time_error = timedelta(minutes=10)
|
|
31
|
-
if utc_datetime <
|
|
30
|
+
if utc_datetime < timezone.now() + time_error:
|
|
32
31
|
raise ValidationError("Expected a future date/time")
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
def date_is_future(value: date) -> None:
|
|
36
|
-
if value <
|
|
35
|
+
if value < timezone.now().date():
|
|
37
36
|
raise ValidationError("Expected a future date")
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from dateutil.relativedelta import MO, relativedelta
|
|
4
4
|
from django.contrib.admin import SimpleListFilter
|
|
5
5
|
from django.db.models import QuerySet
|
|
6
|
+
from django.utils import timezone
|
|
6
7
|
from django.utils.translation import gettext as _
|
|
7
8
|
|
|
8
9
|
from edc_constants.constants import (
|
|
@@ -16,7 +17,6 @@ from edc_constants.constants import (
|
|
|
16
17
|
TODAY,
|
|
17
18
|
TOMORROW,
|
|
18
19
|
)
|
|
19
|
-
from edc_utils import get_utcnow
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class FutureDateListFilter(SimpleListFilter):
|
|
@@ -42,9 +42,9 @@ class FutureDateListFilter(SimpleListFilter):
|
|
|
42
42
|
return {}
|
|
43
43
|
|
|
44
44
|
def queryset(self, request, queryset) -> QuerySet | None:
|
|
45
|
-
morning =
|
|
45
|
+
morning = timezone.now().replace(second=0, hour=0, minute=0)
|
|
46
46
|
monday = morning + relativedelta(weekday=MO(-1))
|
|
47
|
-
night =
|
|
47
|
+
night = timezone.now().replace(second=59, hour=23, minute=59)
|
|
48
48
|
qs = None
|
|
49
49
|
if self.value() == NEXT_WEEK:
|
|
50
50
|
qs = queryset.filter(
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from dateutil.relativedelta import MO, relativedelta
|
|
4
4
|
from django.contrib.admin import SimpleListFilter
|
|
5
5
|
from django.db.models import QuerySet
|
|
6
|
+
from django.utils import timezone
|
|
6
7
|
from django.utils.translation import gettext as _
|
|
7
8
|
|
|
8
9
|
from edc_constants.constants import (
|
|
@@ -17,7 +18,6 @@ from edc_constants.constants import (
|
|
|
17
18
|
TODAY,
|
|
18
19
|
YESTERDAY,
|
|
19
20
|
)
|
|
20
|
-
from edc_utils import get_utcnow
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class PastDateListFilter(SimpleListFilter):
|
|
@@ -45,9 +45,9 @@ class PastDateListFilter(SimpleListFilter):
|
|
|
45
45
|
return {}
|
|
46
46
|
|
|
47
47
|
def queryset(self, request, queryset) -> QuerySet | None:
|
|
48
|
-
morning =
|
|
48
|
+
morning = timezone.now().replace(second=0, hour=0, minute=0)
|
|
49
49
|
monday = morning + relativedelta(weekday=MO(-1))
|
|
50
|
-
night =
|
|
50
|
+
night = timezone.now().replace(second=59, hour=23, minute=59)
|
|
51
51
|
qs = None
|
|
52
52
|
if self.value() == THIS_WEEK:
|
|
53
53
|
qs = queryset.filter(
|
|
@@ -21,16 +21,15 @@ class ModelAdminProtectPiiMixin:
|
|
|
21
21
|
the changelist, add the method name to `extra_pii_attrs`.
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
extra_pii_attrs:
|
|
24
|
+
extra_pii_attrs: tuple[str] | None = ()
|
|
25
25
|
|
|
26
26
|
def get_extra_pii_attrs(self) -> list[str | tuple[str, str]]:
|
|
27
27
|
return self.extra_pii_attrs or []
|
|
28
28
|
|
|
29
|
-
def get_encrypted_fields(self) ->
|
|
29
|
+
def get_encrypted_fields(self) -> tuple[str, ...]:
|
|
30
30
|
encrypted_fields = [f.name for f in get_encrypted_fields(self.model)]
|
|
31
|
-
encrypted_fields.extend(self.get_extra_pii_attrs())
|
|
32
|
-
|
|
33
|
-
return encrypted_fields
|
|
31
|
+
encrypted_fields.extend(*self.get_extra_pii_attrs())
|
|
32
|
+
return tuple(set(encrypted_fields))
|
|
34
33
|
|
|
35
34
|
def get_list_display(self, request) -> tuple[str]:
|
|
36
35
|
list_display = super().get_list_display(request)
|
|
@@ -12,7 +12,7 @@ class OtherCharField(CharField):
|
|
|
12
12
|
def __init__(self, metadata=None, *args, **kwargs):
|
|
13
13
|
self.metadata = metadata
|
|
14
14
|
kwargs.update(blank=True)
|
|
15
|
-
kwargs.update(
|
|
15
|
+
kwargs.update(default="")
|
|
16
16
|
kwargs.setdefault("max_length", self.DEFAULT_MAX_LENGTH)
|
|
17
17
|
kwargs.setdefault("verbose_name", _("If other, please specify ..."))
|
|
18
18
|
self.max_length = kwargs["max_length"]
|
|
@@ -25,7 +25,7 @@ class OtherCharField(CharField):
|
|
|
25
25
|
def deconstruct(self):
|
|
26
26
|
name, path, args, kwargs = super().deconstruct()
|
|
27
27
|
kwargs.update(blank=True)
|
|
28
|
-
kwargs.update(
|
|
28
|
+
kwargs.update(default="")
|
|
29
29
|
kwargs.update(max_length=self.max_length)
|
|
30
30
|
kwargs.update(verbose_name=self.verbose_name)
|
|
31
31
|
if self.metadata is not None:
|
|
@@ -7,6 +7,7 @@ import django_audit_fields.fields.uuid_auto_field
|
|
|
7
7
|
import django_audit_fields.models.audit_model_mixin
|
|
8
8
|
import django_revision.revision_field
|
|
9
9
|
from django.db import migrations, models
|
|
10
|
+
import django.utils.timezone
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class Migration(migrations.Migration):
|
|
@@ -33,14 +34,14 @@ class Migration(migrations.Migration):
|
|
|
33
34
|
"created",
|
|
34
35
|
models.DateTimeField(
|
|
35
36
|
blank=True,
|
|
36
|
-
default=
|
|
37
|
+
default=django.utils.timezone.now,
|
|
37
38
|
),
|
|
38
39
|
),
|
|
39
40
|
(
|
|
40
41
|
"modified",
|
|
41
42
|
models.DateTimeField(
|
|
42
43
|
blank=True,
|
|
43
|
-
default=
|
|
44
|
+
default=django.utils.timezone.now,
|
|
44
45
|
),
|
|
45
46
|
),
|
|
46
47
|
(
|
|
@@ -0,0 +1,49 @@
|
|
|
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_navbar", "0008_alter_edcpermissions_revision"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="edcpermissions",
|
|
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="edcpermissions",
|
|
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="edcpermissions",
|
|
29
|
+
name="locale_created",
|
|
30
|
+
field=models.CharField(
|
|
31
|
+
blank=True,
|
|
32
|
+
default="",
|
|
33
|
+
help_text="Auto-updated by Modeladmin",
|
|
34
|
+
max_length=10,
|
|
35
|
+
verbose_name="Locale created",
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
migrations.AlterField(
|
|
39
|
+
model_name="edcpermissions",
|
|
40
|
+
name="locale_modified",
|
|
41
|
+
field=models.CharField(
|
|
42
|
+
blank=True,
|
|
43
|
+
default="",
|
|
44
|
+
help_text="Auto-updated by Modeladmin",
|
|
45
|
+
max_length=10,
|
|
46
|
+
verbose_name="Locale modified",
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
]
|
|
@@ -7,7 +7,7 @@ from django.db import migrations, models
|
|
|
7
7
|
|
|
8
8
|
import edc_model_fields.fields.hostname_modification_field
|
|
9
9
|
import edc_model_fields.fields.userfield
|
|
10
|
-
import
|
|
10
|
+
import django.utils.timezone
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Migration(migrations.Migration):
|
|
@@ -21,11 +21,11 @@ class Migration(migrations.Migration):
|
|
|
21
21
|
fields=[
|
|
22
22
|
(
|
|
23
23
|
"created",
|
|
24
|
-
models.DateTimeField(blank=True, default=
|
|
24
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
25
25
|
),
|
|
26
26
|
(
|
|
27
27
|
"modified",
|
|
28
|
-
models.DateTimeField(blank=True, default=
|
|
28
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
29
29
|
),
|
|
30
30
|
(
|
|
31
31
|
"user_created",
|
|
@@ -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="notification",
|
|
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="notification",
|
|
@@ -29,9 +28,7 @@ class Migration(migrations.Migration):
|
|
|
29
28
|
migrations.AlterField(
|
|
30
29
|
model_name="notification",
|
|
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="notification",
|
|
@@ -0,0 +1,59 @@
|
|
|
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_notification", "0010_alter_notification_revision"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="notification",
|
|
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="notification",
|
|
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="notification",
|
|
29
|
+
name="locale_created",
|
|
30
|
+
field=models.CharField(
|
|
31
|
+
blank=True,
|
|
32
|
+
default="",
|
|
33
|
+
help_text="Auto-updated by Modeladmin",
|
|
34
|
+
max_length=10,
|
|
35
|
+
verbose_name="Locale created",
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
migrations.AlterField(
|
|
39
|
+
model_name="notification",
|
|
40
|
+
name="locale_modified",
|
|
41
|
+
field=models.CharField(
|
|
42
|
+
blank=True,
|
|
43
|
+
default="",
|
|
44
|
+
help_text="Auto-updated by Modeladmin",
|
|
45
|
+
max_length=10,
|
|
46
|
+
verbose_name="Locale modified",
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
migrations.AlterField(
|
|
50
|
+
model_name="notification",
|
|
51
|
+
name="mailing_list_address",
|
|
52
|
+
field=models.EmailField(
|
|
53
|
+
blank=True,
|
|
54
|
+
default="",
|
|
55
|
+
max_length=254,
|
|
56
|
+
verbose_name="Mailing list address",
|
|
57
|
+
),
|
|
58
|
+
),
|
|
59
|
+
]
|
|
@@ -20,7 +20,7 @@ class Notification(BaseUuidModel):
|
|
|
20
20
|
|
|
21
21
|
display_name = models.CharField(max_length=255, unique=True)
|
|
22
22
|
|
|
23
|
-
mailing_list_address = models.EmailField(_("Mailing list address"), blank=True,
|
|
23
|
+
mailing_list_address = models.EmailField(_("Mailing list address"), blank=True, default="")
|
|
24
24
|
|
|
25
25
|
enabled = models.BooleanField(default=True)
|
|
26
26
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
|
|
1
3
|
from django.apps import apps as django_apps
|
|
2
4
|
from django.conf import settings
|
|
3
5
|
from django.core.exceptions import ObjectDoesNotExist
|
|
4
6
|
from django.core.mail import EmailMessage
|
|
7
|
+
from django.utils import timezone
|
|
5
8
|
from twilio.base.exceptions import TwilioException, TwilioRestException
|
|
6
9
|
from twilio.rest import Client
|
|
7
10
|
|
|
8
11
|
from edc_protocol.research_protocol_config import ResearchProtocolConfig
|
|
9
12
|
from edc_sites.site import SiteNotRegistered, sites
|
|
10
|
-
from edc_utils import get_utcnow
|
|
11
13
|
|
|
12
14
|
from ..site_notifications import site_notifications
|
|
13
15
|
from ..stubs import NotificationModelStub
|
|
@@ -30,7 +32,7 @@ class Notification:
|
|
|
30
32
|
|
|
31
33
|
sms_client = Client
|
|
32
34
|
|
|
33
|
-
email_from:
|
|
35
|
+
email_from: str = get_email_contacts("data_manager")
|
|
34
36
|
email_to: list[str] | None = None # usually a mailing list address
|
|
35
37
|
email_message_cls = EmailMessage
|
|
36
38
|
|
|
@@ -124,9 +126,9 @@ class Notification:
|
|
|
124
126
|
if use_sms:
|
|
125
127
|
sms_sent = self.send_sms(**kwargs)
|
|
126
128
|
self.post_notification_actions(email_sent=email_sent, sms_sent=sms_sent, **kwargs)
|
|
127
|
-
return
|
|
129
|
+
return bool(email_sent or sms_sent)
|
|
128
130
|
|
|
129
|
-
def notify_on_condition(self, **kwargs) -> bool:
|
|
131
|
+
def notify_on_condition(self, **kwargs) -> bool: # noqa: ARG002
|
|
130
132
|
"""Override to conditionally return True if the notification
|
|
131
133
|
should be sent by email and/or sms.
|
|
132
134
|
|
|
@@ -174,7 +176,7 @@ class Notification:
|
|
|
174
176
|
notification_model = notification_model_cls.objects.get(name=self.name)
|
|
175
177
|
return notification_model
|
|
176
178
|
|
|
177
|
-
def get_display_name(self, **kwargs):
|
|
179
|
+
def get_display_name(self, **kwargs): # noqa: ARG002
|
|
178
180
|
return self.display_name
|
|
179
181
|
|
|
180
182
|
def get_template_options(self, instance=None, test_message=None, **kwargs):
|
|
@@ -193,30 +195,28 @@ class Notification:
|
|
|
193
195
|
test_subject_line=(self.email_test_subject_line if test_message else "").strip(),
|
|
194
196
|
test_body_line=self.email_test_body_line if test_message else "",
|
|
195
197
|
test_line=self.sms_test_line if test_message else "",
|
|
196
|
-
message_datetime=
|
|
198
|
+
message_datetime=timezone.now(),
|
|
197
199
|
message_reference="",
|
|
198
200
|
)
|
|
199
201
|
if "subject_identifier" not in template_options:
|
|
200
|
-
|
|
202
|
+
with contextlib.suppress(AttributeError):
|
|
201
203
|
template_options.update(subject_identifier=instance.subject_identifier)
|
|
202
|
-
except AttributeError:
|
|
203
|
-
pass
|
|
204
204
|
if "site_name" not in template_options:
|
|
205
205
|
try:
|
|
206
206
|
site_name = sites.get(instance.site.id).description
|
|
207
207
|
except AttributeError:
|
|
208
208
|
pass
|
|
209
209
|
except SiteNotRegistered as e:
|
|
210
|
-
raise NotificationError(e)
|
|
210
|
+
raise NotificationError(e) from e
|
|
211
211
|
else:
|
|
212
212
|
template_options.update(site_name=site_name.replace("_", " ").title())
|
|
213
213
|
return template_options
|
|
214
214
|
|
|
215
215
|
def send_email(
|
|
216
216
|
self,
|
|
217
|
+
email_to: list[str],
|
|
217
218
|
fail_silently: bool | None = None,
|
|
218
|
-
|
|
219
|
-
email_body_template: str = None,
|
|
219
|
+
email_body_template: str | None = None,
|
|
220
220
|
**kwargs,
|
|
221
221
|
) -> int:
|
|
222
222
|
kwargs.update(**self.get_template_options(**kwargs))
|
|
@@ -10,7 +10,7 @@ import edc_model_fields.fields.hostname_modification_field
|
|
|
10
10
|
import edc_model_fields.fields.other_charfield
|
|
11
11
|
import edc_model_fields.fields.userfield
|
|
12
12
|
import edc_protocol.validators
|
|
13
|
-
import
|
|
13
|
+
import django.utils.timezone
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Migration(migrations.Migration):
|
|
@@ -24,11 +24,11 @@ class Migration(migrations.Migration):
|
|
|
24
24
|
fields=[
|
|
25
25
|
(
|
|
26
26
|
"created",
|
|
27
|
-
models.DateTimeField(blank=True, default=
|
|
27
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
28
28
|
),
|
|
29
29
|
(
|
|
30
30
|
"modified",
|
|
31
|
-
models.DateTimeField(blank=True, default=
|
|
31
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
32
32
|
),
|
|
33
33
|
(
|
|
34
34
|
"user_created",
|
|
@@ -97,7 +97,7 @@ class Migration(migrations.Migration):
|
|
|
97
97
|
(
|
|
98
98
|
"offstudy_datetime",
|
|
99
99
|
models.DateTimeField(
|
|
100
|
-
default=
|
|
100
|
+
default=django.utils.timezone.now,
|
|
101
101
|
validators=[
|
|
102
102
|
edc_protocol.validators.datetime_not_before_study_start,
|
|
103
103
|
edc_model.validators.date.datetime_not_future,
|
|
@@ -14,7 +14,7 @@ import edc_model_fields.fields.other_charfield
|
|
|
14
14
|
import edc_model_fields.fields.userfield
|
|
15
15
|
import edc_protocol.validators
|
|
16
16
|
import edc_sites.models
|
|
17
|
-
import
|
|
17
|
+
import django.utils.timezone
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class Migration(migrations.Migration):
|
|
@@ -30,11 +30,11 @@ class Migration(migrations.Migration):
|
|
|
30
30
|
fields=[
|
|
31
31
|
(
|
|
32
32
|
"created",
|
|
33
|
-
models.DateTimeField(blank=True, default=
|
|
33
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
34
34
|
),
|
|
35
35
|
(
|
|
36
36
|
"modified",
|
|
37
|
-
models.DateTimeField(blank=True, default=
|
|
37
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
38
38
|
),
|
|
39
39
|
(
|
|
40
40
|
"user_created",
|
|
@@ -102,7 +102,7 @@ class Migration(migrations.Migration):
|
|
|
102
102
|
(
|
|
103
103
|
"offstudy_datetime",
|
|
104
104
|
models.DateTimeField(
|
|
105
|
-
default=
|
|
105
|
+
default=django.utils.timezone.now,
|
|
106
106
|
validators=[
|
|
107
107
|
edc_protocol.validators.datetime_not_before_study_start,
|
|
108
108
|
edc_model.validators.date.datetime_not_future,
|
|
@@ -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="historicalsubjectoffstudy",
|
|
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="historicalsubjectoffstudy",
|
|
@@ -29,9 +28,7 @@ class Migration(migrations.Migration):
|
|
|
29
28
|
migrations.AlterField(
|
|
30
29
|
model_name="historicalsubjectoffstudy",
|
|
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="historicalsubjectoffstudy",
|
|
@@ -56,9 +53,7 @@ class Migration(migrations.Migration):
|
|
|
56
53
|
migrations.AlterField(
|
|
57
54
|
model_name="subjectoffstudy",
|
|
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="subjectoffstudy",
|
|
@@ -72,9 +67,7 @@ class Migration(migrations.Migration):
|
|
|
72
67
|
migrations.AlterField(
|
|
73
68
|
model_name="subjectoffstudy",
|
|
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="subjectoffstudy",
|