clinicedc 2.0.5__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.5.dist-info → clinicedc-2.0.7.dist-info}/METADATA +2 -2
- {clinicedc-2.0.5.dist-info → clinicedc-2.0.7.dist-info}/RECORD +387 -336
- 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/form_validators/blood_pressure_form_validator_mixin.py +3 -1
- edc_vitals/utils.py +1 -1
- {clinicedc-2.0.5.dist-info → clinicedc-2.0.7.dist-info}/WHEEL +0 -0
- {clinicedc-2.0.5.dist-info → clinicedc-2.0.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-17 16:53
|
|
2
|
+
|
|
3
|
+
import edc_model_fields.fields.other_charfield
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("edc_offstudy", "0022_alter_historicalsubjectoffstudy_revision_and_more"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name="historicalsubjectoffstudy",
|
|
16
|
+
name="action_identifier",
|
|
17
|
+
field=models.CharField(
|
|
18
|
+
blank=True, db_index=True, default="", max_length=50
|
|
19
|
+
),
|
|
20
|
+
),
|
|
21
|
+
migrations.AlterField(
|
|
22
|
+
model_name="historicalsubjectoffstudy",
|
|
23
|
+
name="action_item_reason",
|
|
24
|
+
field=models.TextField(default="", editable=False),
|
|
25
|
+
),
|
|
26
|
+
migrations.AlterField(
|
|
27
|
+
model_name="historicalsubjectoffstudy",
|
|
28
|
+
name="comment",
|
|
29
|
+
field=models.TextField(
|
|
30
|
+
blank=True,
|
|
31
|
+
default="",
|
|
32
|
+
max_length=500,
|
|
33
|
+
verbose_name="Please provide further details if possible",
|
|
34
|
+
),
|
|
35
|
+
),
|
|
36
|
+
migrations.AlterField(
|
|
37
|
+
model_name="historicalsubjectoffstudy",
|
|
38
|
+
name="device_created",
|
|
39
|
+
field=models.CharField(
|
|
40
|
+
blank=True, default="", max_length=10, verbose_name="Device created"
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
migrations.AlterField(
|
|
44
|
+
model_name="historicalsubjectoffstudy",
|
|
45
|
+
name="device_modified",
|
|
46
|
+
field=models.CharField(
|
|
47
|
+
blank=True, default="", max_length=10, verbose_name="Device modified"
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
migrations.AlterField(
|
|
51
|
+
model_name="historicalsubjectoffstudy",
|
|
52
|
+
name="locale_created",
|
|
53
|
+
field=models.CharField(
|
|
54
|
+
blank=True,
|
|
55
|
+
default="",
|
|
56
|
+
help_text="Auto-updated by Modeladmin",
|
|
57
|
+
max_length=10,
|
|
58
|
+
verbose_name="Locale created",
|
|
59
|
+
),
|
|
60
|
+
),
|
|
61
|
+
migrations.AlterField(
|
|
62
|
+
model_name="historicalsubjectoffstudy",
|
|
63
|
+
name="locale_modified",
|
|
64
|
+
field=models.CharField(
|
|
65
|
+
blank=True,
|
|
66
|
+
default="",
|
|
67
|
+
help_text="Auto-updated by Modeladmin",
|
|
68
|
+
max_length=10,
|
|
69
|
+
verbose_name="Locale modified",
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
migrations.AlterField(
|
|
73
|
+
model_name="historicalsubjectoffstudy",
|
|
74
|
+
name="other_offstudy_reason",
|
|
75
|
+
field=edc_model_fields.fields.other_charfield.OtherCharField(
|
|
76
|
+
blank=True,
|
|
77
|
+
default="",
|
|
78
|
+
max_length=35,
|
|
79
|
+
verbose_name="If other, please specify ...",
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
migrations.AlterField(
|
|
83
|
+
model_name="historicalsubjectoffstudy",
|
|
84
|
+
name="parent_action_identifier",
|
|
85
|
+
field=models.CharField(
|
|
86
|
+
blank=True,
|
|
87
|
+
default="",
|
|
88
|
+
help_text="action identifier that links to parent reference model instance.",
|
|
89
|
+
max_length=30,
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
migrations.AlterField(
|
|
93
|
+
model_name="historicalsubjectoffstudy",
|
|
94
|
+
name="related_action_identifier",
|
|
95
|
+
field=models.CharField(
|
|
96
|
+
blank=True,
|
|
97
|
+
default="",
|
|
98
|
+
help_text="action identifier that links to related reference model instance.",
|
|
99
|
+
max_length=30,
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
migrations.AlterField(
|
|
103
|
+
model_name="subjectoffstudy",
|
|
104
|
+
name="action_identifier",
|
|
105
|
+
field=models.CharField(blank=True, default="", max_length=50, unique=True),
|
|
106
|
+
),
|
|
107
|
+
migrations.AlterField(
|
|
108
|
+
model_name="subjectoffstudy",
|
|
109
|
+
name="action_item_reason",
|
|
110
|
+
field=models.TextField(default="", editable=False),
|
|
111
|
+
),
|
|
112
|
+
migrations.AlterField(
|
|
113
|
+
model_name="subjectoffstudy",
|
|
114
|
+
name="comment",
|
|
115
|
+
field=models.TextField(
|
|
116
|
+
blank=True,
|
|
117
|
+
default="",
|
|
118
|
+
max_length=500,
|
|
119
|
+
verbose_name="Please provide further details if possible",
|
|
120
|
+
),
|
|
121
|
+
),
|
|
122
|
+
migrations.AlterField(
|
|
123
|
+
model_name="subjectoffstudy",
|
|
124
|
+
name="device_created",
|
|
125
|
+
field=models.CharField(
|
|
126
|
+
blank=True, default="", max_length=10, verbose_name="Device created"
|
|
127
|
+
),
|
|
128
|
+
),
|
|
129
|
+
migrations.AlterField(
|
|
130
|
+
model_name="subjectoffstudy",
|
|
131
|
+
name="device_modified",
|
|
132
|
+
field=models.CharField(
|
|
133
|
+
blank=True, default="", max_length=10, verbose_name="Device modified"
|
|
134
|
+
),
|
|
135
|
+
),
|
|
136
|
+
migrations.AlterField(
|
|
137
|
+
model_name="subjectoffstudy",
|
|
138
|
+
name="locale_created",
|
|
139
|
+
field=models.CharField(
|
|
140
|
+
blank=True,
|
|
141
|
+
default="",
|
|
142
|
+
help_text="Auto-updated by Modeladmin",
|
|
143
|
+
max_length=10,
|
|
144
|
+
verbose_name="Locale created",
|
|
145
|
+
),
|
|
146
|
+
),
|
|
147
|
+
migrations.AlterField(
|
|
148
|
+
model_name="subjectoffstudy",
|
|
149
|
+
name="locale_modified",
|
|
150
|
+
field=models.CharField(
|
|
151
|
+
blank=True,
|
|
152
|
+
default="",
|
|
153
|
+
help_text="Auto-updated by Modeladmin",
|
|
154
|
+
max_length=10,
|
|
155
|
+
verbose_name="Locale modified",
|
|
156
|
+
),
|
|
157
|
+
),
|
|
158
|
+
migrations.AlterField(
|
|
159
|
+
model_name="subjectoffstudy",
|
|
160
|
+
name="other_offstudy_reason",
|
|
161
|
+
field=edc_model_fields.fields.other_charfield.OtherCharField(
|
|
162
|
+
blank=True,
|
|
163
|
+
default="",
|
|
164
|
+
max_length=35,
|
|
165
|
+
verbose_name="If other, please specify ...",
|
|
166
|
+
),
|
|
167
|
+
),
|
|
168
|
+
migrations.AlterField(
|
|
169
|
+
model_name="subjectoffstudy",
|
|
170
|
+
name="parent_action_identifier",
|
|
171
|
+
field=models.CharField(
|
|
172
|
+
blank=True,
|
|
173
|
+
default="",
|
|
174
|
+
help_text="action identifier that links to parent reference model instance.",
|
|
175
|
+
max_length=30,
|
|
176
|
+
),
|
|
177
|
+
),
|
|
178
|
+
migrations.AlterField(
|
|
179
|
+
model_name="subjectoffstudy",
|
|
180
|
+
name="related_action_identifier",
|
|
181
|
+
field=models.CharField(
|
|
182
|
+
blank=True,
|
|
183
|
+
default="",
|
|
184
|
+
help_text="action identifier that links to related reference model instance.",
|
|
185
|
+
max_length=30,
|
|
186
|
+
),
|
|
187
|
+
),
|
|
188
|
+
]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-18 00:24
|
|
2
|
+
|
|
3
|
+
import django.utils.timezone
|
|
4
|
+
import edc_model.validators.date
|
|
5
|
+
import edc_protocol.validators
|
|
6
|
+
from django.db import migrations, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
(
|
|
13
|
+
"edc_offstudy",
|
|
14
|
+
"0023_alter_historicalsubjectoffstudy_action_identifier_and_more",
|
|
15
|
+
),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
operations = [
|
|
19
|
+
migrations.AlterField(
|
|
20
|
+
model_name="historicalsubjectoffstudy",
|
|
21
|
+
name="offstudy_datetime",
|
|
22
|
+
field=models.DateTimeField(
|
|
23
|
+
default=django.utils.timezone.now,
|
|
24
|
+
validators=[
|
|
25
|
+
edc_protocol.validators.datetime_not_before_study_start,
|
|
26
|
+
edc_model.validators.date.datetime_not_future,
|
|
27
|
+
],
|
|
28
|
+
verbose_name="Off-study date and time",
|
|
29
|
+
),
|
|
30
|
+
),
|
|
31
|
+
migrations.AlterField(
|
|
32
|
+
model_name="subjectoffstudy",
|
|
33
|
+
name="offstudy_datetime",
|
|
34
|
+
field=models.DateTimeField(
|
|
35
|
+
default=django.utils.timezone.now,
|
|
36
|
+
validators=[
|
|
37
|
+
edc_protocol.validators.datetime_not_before_study_start,
|
|
38
|
+
edc_model.validators.date.datetime_not_future,
|
|
39
|
+
],
|
|
40
|
+
verbose_name="Off-study date and time",
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
]
|
|
@@ -3,12 +3,13 @@ from zoneinfo import ZoneInfo
|
|
|
3
3
|
from django.conf import settings
|
|
4
4
|
from django.core.exceptions import ValidationError
|
|
5
5
|
from django.db import models
|
|
6
|
+
from django.utils import timezone
|
|
6
7
|
|
|
7
8
|
from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
|
|
8
9
|
from edc_model.validators import datetime_not_future
|
|
9
10
|
from edc_model_fields.fields import OtherCharField
|
|
10
11
|
from edc_protocol.validators import datetime_not_before_study_start
|
|
11
|
-
from edc_utils import convert_php_dateformat
|
|
12
|
+
from edc_utils import convert_php_dateformat
|
|
12
13
|
from edc_visit_schedule.utils import (
|
|
13
14
|
off_all_schedules_or_raise,
|
|
14
15
|
offstudy_datetime_after_all_offschedule_datetimes,
|
|
@@ -39,7 +40,7 @@ class OffstudyModelMixin(UniqueSubjectIdentifierFieldMixin, models.Model):
|
|
|
39
40
|
offstudy_datetime = models.DateTimeField(
|
|
40
41
|
verbose_name="Off-study date and time",
|
|
41
42
|
validators=[datetime_not_before_study_start, datetime_not_future],
|
|
42
|
-
default=
|
|
43
|
+
default=timezone.now,
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
report_datetime = models.DateTimeField(null=True, editable=False)
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import contextlib
|
|
4
4
|
import sys
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
import pandas as pd
|
|
7
8
|
from django.apps import apps as django_apps
|
|
8
9
|
from django.conf import settings
|
|
9
10
|
from django.core.management.color import color_style
|
|
10
11
|
from django.db.models import QuerySet
|
|
12
|
+
from django.utils import timezone
|
|
11
13
|
|
|
12
14
|
from edc_export.exceptions import (
|
|
13
15
|
ExporterExportFolder,
|
|
@@ -15,7 +17,6 @@ from edc_export.exceptions import (
|
|
|
15
17
|
ExporterInvalidExportFormat,
|
|
16
18
|
)
|
|
17
19
|
from edc_export.utils import get_base_dir
|
|
18
|
-
from edc_utils import get_utcnow
|
|
19
20
|
|
|
20
21
|
from ..site_values_mappings import site_values_mappings
|
|
21
22
|
from ..utils import get_export_folder, get_model_from_table_name
|
|
@@ -24,9 +25,7 @@ style = color_style()
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class Exported:
|
|
27
|
-
def __init__(
|
|
28
|
-
self, path: str = None, model_name: str = None, record_count: int | None = None
|
|
29
|
-
):
|
|
28
|
+
def __init__(self, path: Path, model_name: str, record_count: int):
|
|
30
29
|
self.path = path
|
|
31
30
|
self.model_name = model_name
|
|
32
31
|
self.record_count = record_count
|
|
@@ -53,7 +52,7 @@ class CsvExporter:
|
|
|
53
52
|
data_label: str | None = None,
|
|
54
53
|
app_label: str | None = None,
|
|
55
54
|
sort_by: list | tuple | str | None = None,
|
|
56
|
-
export_folder:
|
|
55
|
+
export_folder: Path | None = None,
|
|
57
56
|
delimiter: str | None = None,
|
|
58
57
|
date_format: str | None = None,
|
|
59
58
|
index: bool | None = None,
|
|
@@ -75,13 +74,11 @@ class CsvExporter:
|
|
|
75
74
|
self.verbose = verbose
|
|
76
75
|
if not self.export_folder:
|
|
77
76
|
raise ExporterExportFolder("Invalid export folder. Got None")
|
|
78
|
-
if not
|
|
77
|
+
if not self.export_folder.exists():
|
|
79
78
|
raise ExporterExportFolder(f"Invalid export folder. Got {self.export_folder}")
|
|
80
79
|
if self.model_name:
|
|
81
|
-
|
|
80
|
+
with contextlib.suppress(LookupError, AttributeError):
|
|
82
81
|
self.model_cls = django_apps.get_model(self.model_name)
|
|
83
|
-
except (LookupError, AttributeError):
|
|
84
|
-
pass
|
|
85
82
|
elif self.table_name:
|
|
86
83
|
self.model_cls = get_model_from_table_name(table_name)
|
|
87
84
|
if self.model_cls:
|
|
@@ -89,7 +86,7 @@ class CsvExporter:
|
|
|
89
86
|
self.data_label = data_label or model_name or table_name
|
|
90
87
|
|
|
91
88
|
def to_format(
|
|
92
|
-
self, export_format, dataframe
|
|
89
|
+
self, export_format: str, dataframe: pd.DataFrame, export_folder: Path, **kwargs
|
|
93
90
|
) -> Exported:
|
|
94
91
|
"""Returns the full path of the written CSV file if the
|
|
95
92
|
dataframe is exported otherwise None.
|
|
@@ -109,18 +106,18 @@ class CsvExporter:
|
|
|
109
106
|
if not dataframe.empty:
|
|
110
107
|
path = self.get_path()
|
|
111
108
|
if self.sort_by:
|
|
112
|
-
dataframe.sort_values(by=self.sort_by
|
|
109
|
+
dataframe = dataframe.sort_values(by=self.sort_by)
|
|
113
110
|
if self.verbose:
|
|
114
111
|
sys.stdout.write(f"( ) {self.model_name} ... \r")
|
|
115
112
|
if export_format == "csv":
|
|
116
|
-
path =
|
|
113
|
+
path = path.with_suffix(".csv")
|
|
117
114
|
dataframe.to_csv(path_or_buf=path, **self.csv_options)
|
|
118
115
|
elif export_format == "stata":
|
|
119
|
-
path =
|
|
116
|
+
path = path.with_suffix(".dta")
|
|
120
117
|
dta_version: str | None = kwargs.pop("dta_version", None)
|
|
121
118
|
dta_version = int(dta_version) if dta_version else None
|
|
122
119
|
dataframe.to_stata(
|
|
123
|
-
path=path, **self.stata_options, version=dta_version, **kwargs
|
|
120
|
+
path=str(path), **self.stata_options, version=dta_version, **kwargs
|
|
124
121
|
)
|
|
125
122
|
else:
|
|
126
123
|
raise ExporterInvalidExportFormat(
|
|
@@ -135,7 +132,7 @@ class CsvExporter:
|
|
|
135
132
|
sys.stdout.write(f"(?) {self.model_name} empty \n")
|
|
136
133
|
return Exported(path, self.model_name, record_count)
|
|
137
134
|
|
|
138
|
-
def to_csv(self, dataframe: pd.DataFrame
|
|
135
|
+
def to_csv(self, dataframe: pd.DataFrame, export_folder: Path) -> Exported:
|
|
139
136
|
"""Returns the full path of the written CSV file if the
|
|
140
137
|
dataframe is exported otherwise None.
|
|
141
138
|
|
|
@@ -149,9 +146,9 @@ class CsvExporter:
|
|
|
149
146
|
|
|
150
147
|
def to_stata(
|
|
151
148
|
self,
|
|
152
|
-
dataframe: pd.DataFrame
|
|
153
|
-
export_folder:
|
|
154
|
-
dta_version: str = None,
|
|
149
|
+
dataframe: pd.DataFrame,
|
|
150
|
+
export_folder: Path,
|
|
151
|
+
dta_version: str | None = None,
|
|
155
152
|
) -> Exported:
|
|
156
153
|
"""Returns the full path of the written STATA file if the
|
|
157
154
|
dataframe is exported otherwise None.
|
|
@@ -184,16 +181,16 @@ class CsvExporter:
|
|
|
184
181
|
"""Returns default options for dataframe.to_stata()."""
|
|
185
182
|
return dict(data_label=f"{self.data_label}.dta")
|
|
186
183
|
|
|
187
|
-
def get_path(self) ->
|
|
184
|
+
def get_path(self) -> Path:
|
|
188
185
|
"""Returns a full path with filename."""
|
|
189
186
|
root_dir = self.export_folder
|
|
190
|
-
if not
|
|
187
|
+
if not root_dir.exists():
|
|
191
188
|
raise ExporterExportFolder(f"Base folder does not exist. Got {root_dir}.")
|
|
192
|
-
base_dir
|
|
193
|
-
if not
|
|
194
|
-
|
|
195
|
-
path =
|
|
196
|
-
if
|
|
189
|
+
base_dir = get_base_dir()
|
|
190
|
+
if not (root_dir / base_dir).exists():
|
|
191
|
+
(root_dir / base_dir).mkdir(parents=True, exist_ok=False)
|
|
192
|
+
path = root_dir / base_dir / self.filename
|
|
193
|
+
if path.exists() and not self.file_exists_ok:
|
|
197
194
|
raise ExporterFileExists(
|
|
198
195
|
f"File '{path}' exists! Not exporting {self.model_name}.\n"
|
|
199
196
|
)
|
|
@@ -212,7 +209,7 @@ class CsvExporter:
|
|
|
212
209
|
if not timestamp_format:
|
|
213
210
|
suffix = ""
|
|
214
211
|
else:
|
|
215
|
-
suffix = f"_{
|
|
212
|
+
suffix = f"_{timezone.now().strftime(timestamp_format)}"
|
|
216
213
|
prefix = (self.model_name or self.data_label).replace("-", "_").replace(".", "_")
|
|
217
214
|
filename = f"{prefix}{suffix}"
|
|
218
215
|
return filename
|
|
@@ -229,15 +226,14 @@ class CsvExporter:
|
|
|
229
226
|
choices = {}
|
|
230
227
|
if self.model_cls:
|
|
231
228
|
for field_cls in self.model_cls._meta.get_fields():
|
|
232
|
-
if field_cls.get_internal_type() == "CharField":
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
choices.update({field_cls.name: responses})
|
|
229
|
+
if field_cls.get_internal_type() == "CharField" and field_cls.choices:
|
|
230
|
+
responses = []
|
|
231
|
+
for tpl in field_cls.choices:
|
|
232
|
+
if mapped_choice := site_values_mappings.get_by_choices(tpl):
|
|
233
|
+
responses.append([mapped_choice[0], mapped_choice[1]])
|
|
234
|
+
else:
|
|
235
|
+
responses.append([tpl[0], tpl[1]])
|
|
236
|
+
choices.update({field_cls.name: responses})
|
|
241
237
|
for fname, responses in choices.items():
|
|
242
238
|
labels = []
|
|
243
239
|
if fname in list(dataframe.columns):
|
|
@@ -248,7 +244,7 @@ class CsvExporter:
|
|
|
248
244
|
commands.append(f"ren {fname} {fname}_edc")
|
|
249
245
|
commands.append(f"ren {fname}_encoded {fname}")
|
|
250
246
|
commands.append("")
|
|
251
|
-
with
|
|
247
|
+
with (self.get_path() / ".do").open("w") as f:
|
|
252
248
|
f.writelines(f"{command}\n" for command in commands)
|
|
253
249
|
return commands
|
|
254
250
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import TYPE_CHECKING
|
|
4
5
|
|
|
5
6
|
from django.core.management.color import color_style
|
|
@@ -24,7 +25,7 @@ class CsvModelExporter:
|
|
|
24
25
|
queryset: QuerySet | None = None,
|
|
25
26
|
decrypt: bool | None = None,
|
|
26
27
|
sort_by: list | tuple | str | None = None,
|
|
27
|
-
export_folder:
|
|
28
|
+
export_folder: Path | None = None,
|
|
28
29
|
site_ids: list[int] | None = None,
|
|
29
30
|
**kwargs,
|
|
30
31
|
):
|
|
@@ -10,7 +10,7 @@ from django.db import migrations, models
|
|
|
10
10
|
|
|
11
11
|
import edc_model_fields.fields.hostname_modification_field
|
|
12
12
|
import edc_model_fields.fields.userfield
|
|
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",
|
|
@@ -109,11 +109,11 @@ class Migration(migrations.Migration):
|
|
|
109
109
|
fields=[
|
|
110
110
|
(
|
|
111
111
|
"created",
|
|
112
|
-
models.DateTimeField(blank=True, default=
|
|
112
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
113
113
|
),
|
|
114
114
|
(
|
|
115
115
|
"modified",
|
|
116
|
-
models.DateTimeField(blank=True, default=
|
|
116
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
117
117
|
),
|
|
118
118
|
(
|
|
119
119
|
"user_created",
|
|
@@ -179,7 +179,7 @@ class Migration(migrations.Migration):
|
|
|
179
179
|
("summary", models.TextField(null=True)),
|
|
180
180
|
(
|
|
181
181
|
"exported_datetime",
|
|
182
|
-
models.DateTimeField(default=
|
|
182
|
+
models.DateTimeField(default=django.utils.timezone.now),
|
|
183
183
|
),
|
|
184
184
|
(
|
|
185
185
|
"data_request",
|
|
@@ -196,11 +196,11 @@ class Migration(migrations.Migration):
|
|
|
196
196
|
fields=[
|
|
197
197
|
(
|
|
198
198
|
"created",
|
|
199
|
-
models.DateTimeField(blank=True, default=
|
|
199
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
200
200
|
),
|
|
201
201
|
(
|
|
202
202
|
"modified",
|
|
203
|
-
models.DateTimeField(blank=True, default=
|
|
203
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
204
204
|
),
|
|
205
205
|
(
|
|
206
206
|
"user_created",
|
|
@@ -2,12 +2,13 @@ from django.conf import settings
|
|
|
2
2
|
from django.contrib import admin
|
|
3
3
|
from django.template.loader import render_to_string
|
|
4
4
|
from django.urls import reverse
|
|
5
|
+
from django.utils import timezone
|
|
5
6
|
from django.utils.html import format_html
|
|
6
7
|
from django.utils.safestring import mark_safe
|
|
7
8
|
from django_audit_fields.admin import audit_fieldset_tuple
|
|
8
9
|
|
|
9
10
|
from edc_appointment.models import Appointment
|
|
10
|
-
from edc_utils import convert_php_dateformat, formatted_age
|
|
11
|
+
from edc_utils import convert_php_dateformat, formatted_age
|
|
11
12
|
|
|
12
13
|
from ...admin_site import edc_pharmacy_admin
|
|
13
14
|
from ...forms import RxRefillForm
|
|
@@ -21,7 +22,7 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
21
22
|
|
|
22
23
|
ordering: tuple[str, ...] = ("refill_start_datetime",)
|
|
23
24
|
|
|
24
|
-
autocomplete_fields =
|
|
25
|
+
autocomplete_fields = ("dosage_guideline", "formulation")
|
|
25
26
|
|
|
26
27
|
form = RxRefillForm
|
|
27
28
|
|
|
@@ -140,7 +141,7 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
140
141
|
"initials": obj.rx.registered_subject.initials,
|
|
141
142
|
"gender": obj.rx.registered_subject.gender,
|
|
142
143
|
"age_in_years": formatted_age(
|
|
143
|
-
born=obj.rx.registered_subject.dob, reference_dt=
|
|
144
|
+
born=obj.rx.registered_subject.dob, reference_dt=timezone.now()
|
|
144
145
|
),
|
|
145
146
|
"number_of_days": obj.number_of_days,
|
|
146
147
|
"remaining": obj.remaining,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
from django.db.models import QuerySet
|
|
3
3
|
from django.urls import reverse
|
|
4
|
+
from django.utils import timezone
|
|
4
5
|
from django.utils.html import format_html
|
|
5
6
|
from rangefilter.filters import DateRangeFilterBuilder, NumericRangeFilterBuilder
|
|
6
7
|
|
|
@@ -8,7 +9,6 @@ from edc_model_admin.dashboard import ModelAdminDashboardMixin
|
|
|
8
9
|
from edc_model_admin.mixins import TemplatesModelAdminMixin
|
|
9
10
|
from edc_qareports.modeladmin_mixins import QaReportModelAdminMixin
|
|
10
11
|
from edc_sites.admin import SiteModelAdminMixin
|
|
11
|
-
from edc_utils import get_utcnow
|
|
12
12
|
|
|
13
13
|
from ...admin_site import edc_pharmacy_admin
|
|
14
14
|
from ...analytics.dataframes.no_stock_for_subjects_df import stock_for_subjects_df
|
|
@@ -21,7 +21,8 @@ def wrap_html(s, url):
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def update_report(modeladmin, request):
|
|
24
|
-
now =
|
|
24
|
+
now = timezone.now()
|
|
25
|
+
created = 0
|
|
25
26
|
modeladmin.model.objects.all().delete()
|
|
26
27
|
|
|
27
28
|
df = stock_for_subjects_df()
|
|
@@ -50,9 +51,8 @@ def update_report(modeladmin, request):
|
|
|
50
51
|
)
|
|
51
52
|
for _, row in df.iterrows()
|
|
52
53
|
]
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return created
|
|
54
|
+
return len(modeladmin.model.objects.bulk_create(data))
|
|
55
|
+
return created
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
@admin.register(StockAvailability, site=edc_pharmacy_admin)
|
|
@@ -63,7 +63,6 @@ class StockAvailabilityModelAdmin(
|
|
|
63
63
|
TemplatesModelAdminMixin,
|
|
64
64
|
admin.ModelAdmin,
|
|
65
65
|
):
|
|
66
|
-
|
|
67
66
|
queryset_filter: dict | None = None
|
|
68
67
|
qa_report_list_display_insert_pos = 3
|
|
69
68
|
include_note_column = False
|