clinicedc 2.0.6__py3-none-any.whl → 2.0.8__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.

Files changed (495) hide show
  1. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/METADATA +2 -2
  2. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/RECORD +489 -441
  3. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/WHEEL +1 -1
  4. edc_action_item/action.py +1 -1
  5. edc_action_item/action_item_notification.py +2 -2
  6. edc_action_item/auths.py +37 -32
  7. edc_action_item/create_action_item.py +1 -1
  8. edc_action_item/decorators.py +1 -1
  9. edc_action_item/migrations/0001_initial.py +21 -22
  10. edc_action_item/migrations/0006_auto_20180707_1659.py +4 -4
  11. edc_action_item/migrations/0008_auto_20180809_0303.py +4 -4
  12. edc_action_item/migrations/0015_auto_20190114_0250.py +4 -4
  13. edc_action_item/migrations/0017_auto_20190305_0123.py +11 -30
  14. edc_action_item/migrations/0030_edcpermissions.py +3 -2
  15. edc_action_item/migrations/0039_alter_actionitem_auto_created_comment_and_more.py +398 -0
  16. edc_action_item/migrations/0040_alter_actionitem_report_datetime_and_more.py +34 -0
  17. edc_action_item/models/action_item.py +9 -4
  18. edc_action_item/models/action_model_mixin.py +5 -6
  19. edc_action_item/models/reference.py +2 -2
  20. edc_action_item/models/signals.py +22 -23
  21. edc_action_item/post_migrate_signals.py +1 -1
  22. edc_action_item/send_email.py +0 -85
  23. edc_action_item/site_action_items.py +5 -9
  24. edc_action_item/utils.py +3 -3
  25. edc_adherence/migrations/0005_alter_nonadherencereasons_extra_value_and_more.py +36 -0
  26. edc_adherence/model_mixins.py +1 -1
  27. edc_adverse_event/auths.py +55 -51
  28. edc_adverse_event/migrations/0001_initial.py +5 -4
  29. edc_adverse_event/migrations/0002_auto_20190802_0059.py +3 -2
  30. edc_adverse_event/migrations/0008_auto_20220825_0451.py +3 -2
  31. edc_adverse_event/migrations/0009_auto_20220907_0157.py +3 -2
  32. edc_adverse_event/migrations/0016_alter_aeactionclassification_device_created_and_more.py +285 -0
  33. edc_adverse_event/model_mixins/ae_followup/ae_followup_fields_model_mixin.py +2 -2
  34. edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +6 -5
  35. edc_adverse_event/model_mixins/ae_special_interest/aesi_fields_model_mixin.py +2 -2
  36. edc_adverse_event/model_mixins/ae_susar/ae_susar_fields_model_mixin.py +2 -2
  37. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +15 -11
  38. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_methods_model_mixin.py +2 -4
  39. edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +5 -4
  40. edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +6 -3
  41. edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +2 -2
  42. edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +4 -3
  43. edc_adverse_event/modeladmin_mixins/death_report_admin_mixin.py +3 -3
  44. edc_adverse_event/models/signals.py +7 -7
  45. edc_adverse_event/templatetags/edc_adverse_event_extras.py +5 -4
  46. edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +3 -5
  47. edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +6 -8
  48. edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +2 -2
  49. edc_adverse_event/views/tmg/summary_listboard_view.py +3 -2
  50. edc_appointment/admin/appointment_admin.py +2 -2
  51. edc_appointment/admin/list_filters.py +2 -2
  52. edc_appointment/auths.py +14 -10
  53. edc_appointment/creators/appointment_creator.py +1 -1
  54. edc_appointment/creators/appointments_creator.py +1 -1
  55. edc_appointment/form_validators/appointment_form_validator.py +108 -82
  56. edc_appointment/migrations/0003_auto_20161127_2226.py +5 -6
  57. edc_appointment/migrations/0006_auto_20170106_2118.py +5 -5
  58. edc_appointment/migrations/0018_auto_20190305_0123.py +5 -12
  59. edc_appointment/migrations/0050_alter_appointment_appt_type_and_more.py +220 -0
  60. edc_appointment/model_mixins/appointment_fields_model_mixin.py +1 -2
  61. edc_appointment/model_mixins/appointment_methods_model_mixin.py +2 -3
  62. edc_appointment/model_mixins/appointment_model_mixin.py +31 -28
  63. edc_appointment/model_mixins/window_period_model_mixin.py +6 -7
  64. edc_appointment/models/appointment.py +1 -1
  65. edc_appointment/models/signals.py +44 -35
  66. edc_appointment/utils.py +19 -24
  67. edc_appointment/view_utils/appointment_button.py +2 -2
  68. edc_auth/admin/user_admin.py +1 -1
  69. edc_auth/auth_objects/__init__.py +2 -20
  70. edc_auth/auth_objects/default_groups.py +13 -11
  71. edc_auth/auth_objects/default_roles.py +26 -24
  72. edc_auth/auth_updater/auth_updater.py +13 -2
  73. edc_auth/auth_updater/group_updater.py +12 -10
  74. edc_auth/auth_updater/role_updater.py +2 -2
  75. edc_auth/constants.py +10 -0
  76. edc_auth/import_users.py +3 -3
  77. edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +5 -5
  78. edc_auth/migrations/0012_auto_20191026_0034.py +3 -2
  79. edc_auth/migrations/0013_auto_20191026_0055.py +3 -2
  80. edc_auth/migrations/0025_permissions.py +3 -2
  81. edc_auth/migrations/0035_alter_edcpermissions_device_created_and_more.py +85 -0
  82. edc_auth/models/user_profile.py +14 -11
  83. edc_auth/post_migrate_signals.py +1 -1
  84. edc_auth/site_auths.py +80 -67
  85. edc_consent/actions.py +4 -5
  86. edc_consent/auths.py +18 -12
  87. edc_consent/migrations/0001_initial.py +3 -2
  88. edc_consent/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  89. edc_consent/model_mixins/consent_extension_model_mixin.py +4 -5
  90. edc_consent/model_mixins/requires_consent_fields_model_mixin.py +2 -2
  91. edc_consent/utils.py +1 -1
  92. edc_constants/constants.py +1 -0
  93. edc_crf/auths.py +5 -0
  94. edc_crf/migrations/0001_initial.py +3 -2
  95. edc_crf/migrations/0009_alter_crfstatus_device_created_and_more.py +54 -0
  96. edc_dashboard/auths.py +10 -6
  97. edc_dashboard/migrations/0001_initial.py +3 -2
  98. edc_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  99. edc_dashboard/templatetags/edc_dashboard_extras.py +3 -2
  100. edc_dashboard/url_config.py +92 -83
  101. edc_dashboard/url_names.py +4 -4
  102. edc_dashboard/view_mixins/url_request_context_mixin.py +6 -5
  103. edc_data_manager/action_items.py +4 -6
  104. edc_data_manager/admin/actions.py +5 -5
  105. edc_data_manager/admin/data_query_admin.py +12 -11
  106. edc_data_manager/auths.py +37 -34
  107. edc_data_manager/handlers/handlers.py +6 -7
  108. edc_data_manager/migrations/0001_initial.py +19 -19
  109. edc_data_manager/migrations/0025_edcpermissions.py +3 -2
  110. edc_data_manager/migrations/0040_alter_datadictionary_device_created_and_more.py +327 -0
  111. edc_data_manager/migrations/0041_alter_dataquery_dm_user_and_more.py +164 -0
  112. edc_data_manager/models/data_query.py +5 -5
  113. edc_data_manager/models/model_mixins.py +8 -8
  114. edc_data_manager/rule/query_rule_wrapper.py +7 -7
  115. edc_data_manager/rule/rule_runner.py +4 -3
  116. edc_document_status/model_mixins.py +1 -1
  117. edc_egfr/egfr.py +11 -7
  118. edc_egfr/model_mixins/egfr_model_mixin.py +3 -7
  119. edc_export/admin/data_request_admin.py +2 -2
  120. edc_export/archive_exporter.py +7 -5
  121. edc_export/auths.py +32 -28
  122. edc_export/files_archiver.py +3 -2
  123. edc_export/migrations/0001_initial.py +26 -26
  124. edc_export/migrations/0004_auto_20190305_0123.py +25 -72
  125. edc_export/migrations/0013_edcpermissions.py +3 -2
  126. edc_export/migrations/0022_alter_datarequest_description_and_more.py +611 -0
  127. edc_export/migrations/0023_alter_datarequesthistory_archive_filename_and_more.py +29 -0
  128. edc_export/model_exporter/file_history_updater.py +10 -10
  129. edc_export/model_exporter/model_exporter.py +17 -15
  130. edc_export/model_exporter/object_history_helpers.py +2 -2
  131. edc_export/models/data_request_history.py +4 -4
  132. edc_export/utils.py +10 -15
  133. edc_facility/auths.py +8 -3
  134. edc_facility/facility.py +16 -22
  135. edc_facility/import_holidays.py +13 -13
  136. edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +8 -7
  137. edc_facility/migrations/0016_alter_healthfacility_device_created_and_more.py +139 -0
  138. edc_facility/migrations/0017_alter_healthfacility_gps_and_more.py +54 -0
  139. edc_facility/model_mixins.py +5 -5
  140. edc_form_label/custom_label_condition.py +11 -8
  141. edc_form_label/form_label.py +1 -1
  142. edc_form_runners/auths.py +11 -6
  143. edc_form_runners/form_runner.py +3 -5
  144. edc_form_runners/migrations/0001_initial.py +3 -2
  145. edc_form_runners/migrations/0005_alter_issue_device_created_and_more.py +49 -0
  146. edc_form_validators/applicable_field_validator.py +7 -6
  147. edc_form_validators/base_form_validator.py +8 -9
  148. edc_form_validators/other_specify_field_validator.py +2 -8
  149. edc_form_validators/required_field_validator.py +19 -16
  150. edc_identifier/migrations/0001_squashed_0018_auto_20180128_1054.py +3 -3
  151. edc_identifier/migrations/0002_auto_20190305_0123.py +3 -6
  152. edc_identifier/migrations/0006_auto_20161127_2226.py +15 -15
  153. edc_identifier/migrations/0007_auto_20161204_2227.py +3 -3
  154. edc_identifier/migrations/0009_auto_20161221_2323.py +3 -5
  155. edc_identifier/migrations/0010_auto_20170112_0602.py +17 -17
  156. edc_identifier/migrations/0011_alter_identifiermodel_device_created_and_more.py +79 -0
  157. edc_identifier/model_mixins.py +1 -1
  158. edc_identifier/models.py +9 -9
  159. edc_identifier/research_identifier.py +11 -10
  160. edc_identifier/simple_identifier.py +9 -5
  161. edc_identifier/subject_identifier.py +3 -2
  162. edc_lab/auths.py +26 -23
  163. edc_lab/lab/aliquot_creator.py +5 -8
  164. edc_lab/lab/primary_aliquot.py +14 -5
  165. edc_lab/migrations/0001_initial.py +29 -29
  166. edc_lab/migrations/0008_auto_20170921_0719.py +3 -3
  167. edc_lab/migrations/0010_auto_20171127_1541.py +15 -15
  168. edc_lab/migrations/0012_auto_20180114_1438.py +3 -3
  169. edc_lab/migrations/0019_auto_20190305_0123.py +43 -127
  170. edc_lab/migrations/0036_alter_aliquot_comment_alter_aliquot_device_created_and_more.py +1139 -0
  171. edc_lab/migrations/0037_alter_historicalorder_order_datetime_and_more.py +31 -0
  172. edc_lab/model_mixins/aliquot/aliquot_identifier_model_mixin.py +2 -2
  173. edc_lab/model_mixins/aliquot/aliquot_model_mixin.py +2 -2
  174. edc_lab/model_mixins/panel_model_mixin.py +18 -7
  175. edc_lab/model_mixins/requisition/crf_with_requisition_model_mixin.py +2 -4
  176. edc_lab/model_mixins/requisition/requisition_model_mixin.py +13 -16
  177. edc_lab/model_mixins/requisition/requisition_verify_model_mixin.py +1 -1
  178. edc_lab/model_mixins/result/result_item_model_mixin.py +4 -4
  179. edc_lab/model_mixins/shipping/manifest_model_mixin.py +4 -5
  180. edc_lab/model_mixins/shipping/verify_model_mixin.py +4 -6
  181. edc_lab/models/aliquot.py +2 -2
  182. edc_lab/models/box.py +1 -1
  183. edc_lab/models/box_item.py +6 -7
  184. edc_lab/models/manifest/manifest.py +3 -3
  185. edc_lab/models/manifest/manifest_item.py +7 -7
  186. edc_lab/models/manifest/shipper.py +3 -4
  187. edc_lab/models/order.py +6 -4
  188. edc_lab/models/panel.py +4 -4
  189. edc_lab/models/result.py +2 -2
  190. edc_lab/models/result_item.py +2 -2
  191. edc_lab_dashboard/auths.py +16 -11
  192. edc_lab_dashboard/migrations/0001_initial.py +3 -2
  193. edc_lab_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  194. edc_lab_dashboard/views/action_views/receive_view.py +2 -2
  195. edc_lab_dashboard/views/action_views/verify_box_item_view.py +2 -2
  196. edc_lab_results/calculate_missing.py +8 -8
  197. edc_lab_results/form_validator_mixins/blood_results_form_validator_mixin.py +2 -2
  198. edc_lab_results/get_summary.py +26 -25
  199. edc_lab_results/model_mixins/blood_result_model_mixin.py +9 -7
  200. edc_lab_results/model_mixins/fbg_model_mixin.py +3 -3
  201. edc_lab_results/model_mixins/glucose_model_mixin.py +3 -3
  202. edc_lab_results/model_mixins/hba1c_model_mixin.py +3 -3
  203. edc_label/auths.py +6 -1
  204. edc_label/label_template.py +8 -8
  205. edc_label/migrations/0001_initial.py +3 -2
  206. edc_label/migrations/0007_alter_zpllabeltemplates_device_created_and_more.py +49 -0
  207. edc_list_data/list_model_maker.py +2 -2
  208. edc_list_data/load_list_data.py +11 -14
  209. edc_list_data/load_model_data.py +3 -3
  210. edc_list_data/model_mixins.py +12 -4
  211. edc_list_data/post_migrate_signals.py +1 -1
  212. edc_list_data/preload_data.py +4 -4
  213. edc_list_data/row.py +1 -1
  214. edc_list_data/site_list_data.py +6 -5
  215. edc_listboard/migrations/0001_initial.py +3 -2
  216. edc_listboard/migrations/0007_alter_listboard_device_created_and_more.py +49 -0
  217. edc_locator/auths.py +18 -13
  218. edc_locator/migrations/0001_initial.py +7 -7
  219. edc_locator/migrations/0018_auto_20190305_0123.py +5 -12
  220. edc_locator/migrations/0040_alter_historicalsubjectlocator_action_identifier_and_more.py +187 -0
  221. edc_locator/migrations/0041_alter_historicalsubjectlocator_report_datetime_and_more.py +27 -0
  222. edc_locator/model_mixins/locator_model_mixin.py +2 -2
  223. edc_locator/model_mixins/subject_contact_fields_mixin.py +1 -1
  224. edc_locator/modeladmin_mixins.py +5 -4
  225. edc_ltfu/model_mixins.py +7 -5
  226. edc_metadata/auths.py +11 -7
  227. edc_metadata/metadata/metadata.py +1 -1
  228. edc_metadata/metadata_rules/crf/crf_rule.py +1 -1
  229. edc_metadata/metadata_rules/decorators.py +1 -1
  230. edc_metadata/metadata_rules/metadata_rule_evaluator.py +5 -3
  231. edc_metadata/metadata_rules/rule.py +2 -3
  232. edc_metadata/metadata_rules/rule_evaluator.py +1 -1
  233. edc_metadata/migrations/0002_auto_20161127_2226.py +5 -5
  234. edc_metadata/migrations/0005_auto_20170112_0602.py +5 -5
  235. edc_metadata/migrations/0011_auto_20190305_0123.py +5 -12
  236. edc_metadata/migrations/0031_alter_crfmetadata_device_created_and_more.py +120 -0
  237. edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +7 -4
  238. edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +5 -2
  239. edc_metadata/models/crf_metadata.py +5 -5
  240. edc_metadata/models/crf_metadata_model_mixin.py +4 -5
  241. edc_metadata/models/requisition_metadata.py +6 -6
  242. edc_metadata/models/signals.py +10 -11
  243. edc_metadata/views/refresh_metadata_actions_view.py +3 -3
  244. edc_model/models/address_mixin.py +6 -6
  245. edc_model/models/fields/initials_field.py +2 -1
  246. edc_model/models/historical_records.py +2 -9
  247. edc_model/models/url_model_mixin.py +2 -2
  248. edc_model/validators/date.py +7 -8
  249. edc_model_admin/list_filters/future_date_list_filter.py +3 -3
  250. edc_model_admin/list_filters/past_date_list_filter.py +3 -3
  251. edc_model_admin/mixins/model_admin_protect_pii_mixin.py +4 -5
  252. edc_model_fields/fields/other_charfield.py +2 -2
  253. edc_navbar/auths.py +18 -13
  254. edc_navbar/migrations/0004_auto_20220825_0451.py +3 -2
  255. edc_navbar/migrations/0009_alter_edcpermissions_device_created_and_more.py +49 -0
  256. edc_notification/auths.py +9 -4
  257. edc_notification/migrations/0001_initial.py +3 -3
  258. edc_notification/migrations/0004_auto_20190305_0123.py +3 -6
  259. edc_notification/migrations/0011_alter_notification_device_created_and_more.py +59 -0
  260. edc_notification/models/notification.py +1 -1
  261. edc_notification/notification/graded_event_notification.py +2 -2
  262. edc_notification/notification/model_notification.py +3 -30
  263. edc_notification/notification/new_model_notification.py +1 -1
  264. edc_notification/notification/notification.py +12 -12
  265. edc_notification/notification/updated_model_notification.py +2 -2
  266. edc_offstudy/auths.py +12 -7
  267. edc_offstudy/migrations/0001_initial.py +4 -4
  268. edc_offstudy/migrations/0002_auto_20180921_0434.py +4 -4
  269. edc_offstudy/migrations/0005_auto_20190305_0123.py +5 -12
  270. edc_offstudy/migrations/0023_alter_historicalsubjectoffstudy_action_identifier_and_more.py +188 -0
  271. edc_offstudy/migrations/0024_alter_historicalsubjectoffstudy_offstudy_datetime_and_more.py +43 -0
  272. edc_offstudy/model_mixins/offstudy_model_mixin.py +3 -2
  273. edc_pdutils/df_exporters/csv_exporter.py +33 -37
  274. edc_pdutils/df_exporters/csv_model_exporter.py +7 -3
  275. edc_pdutils/migrations/0001_initial.py +8 -8
  276. edc_pharmacy/admin/prescription/rx_refill_admin.py +4 -3
  277. edc_pharmacy/admin/reports/stock_availability_admin.py +5 -6
  278. edc_pharmacy/auths.py +19 -15
  279. edc_pharmacy/migrations/0001_initial.py +64 -63
  280. edc_pharmacy/migrations/0015_auto_20220913_2139.py +26 -26
  281. edc_pharmacy/migrations/0024_allocation_assignment_containerunits_dispense_and_more.py +81 -86
  282. edc_pharmacy/migrations/0037_remove_historicalstock_confirmed_at_site_by_and_more.py +5 -5
  283. edc_pharmacy/migrations/0039_remove_dispense_registered_subject_and_more.py +7 -8
  284. edc_pharmacy/migrations/0049_remove_stocktransferconfirmation_stock_and_more.py +12 -12
  285. edc_pharmacy/migrations/0050_remove_stocktransferconfirmation2_location_and_more.py +5 -5
  286. edc_pharmacy/migrations/0051_alter_historicalstocktransferconfirmationitem_options_and_more.py +3 -4
  287. edc_pharmacy/migrations/0053_alter_location_managers_alter_historicalstock_lot_and_more.py +3 -3
  288. edc_pharmacy/migrations/0057_scanduplicates.py +3 -3
  289. edc_pharmacy/migrations/0060_alter_container_max_per_subject_and_more.py +13 -15
  290. edc_pharmacy/migrations/0068_stockout.py +2 -3
  291. edc_pharmacy/migrations/0076_historicalstockadjustment_stockadjustment.py +5 -5
  292. edc_pharmacy/migrations/0077_historicalstockadjustment_adjustment_datetime_and_more.py +3 -4
  293. edc_pharmacy/migrations/0081_historicalconfirmation_confirmation.py +8 -8
  294. edc_pharmacy/migrations/0084_confirmationatsiteitem_and_more.py +0 -2
  295. edc_pharmacy/migrations/0089_alter_allocation_allocated_by_and_more.py +3284 -0
  296. edc_pharmacy/migrations/0090_alter_allocation_allocation_datetime_and_more.py +227 -0
  297. edc_pharmacy/model_mixins/study_medication_refill_model_mixin.py +2 -2
  298. edc_pharmacy/models/medication/formulation.py +5 -7
  299. edc_pharmacy/models/medication/medication.py +3 -3
  300. edc_pharmacy/models/model_mixins.py +10 -11
  301. edc_pharmacy/models/prescription/rx.py +13 -12
  302. edc_pharmacy/models/prescription/rx_refill.py +0 -1
  303. edc_pharmacy/models/stock/allocation.py +3 -3
  304. edc_pharmacy/models/stock/confirmation.py +3 -3
  305. edc_pharmacy/models/stock/confirmation_at_site.py +3 -2
  306. edc_pharmacy/models/stock/confirmation_at_site_item.py +3 -4
  307. edc_pharmacy/models/stock/dispense.py +5 -6
  308. edc_pharmacy/models/stock/dispense_item.py +2 -2
  309. edc_pharmacy/models/stock/location.py +3 -4
  310. edc_pharmacy/models/stock/lot.py +6 -7
  311. edc_pharmacy/models/stock/order.py +1 -1
  312. edc_pharmacy/models/stock/receive.py +3 -3
  313. edc_pharmacy/models/stock/receive_item.py +4 -4
  314. edc_pharmacy/models/stock/repack_request.py +2 -2
  315. edc_pharmacy/models/stock/stock.py +12 -18
  316. edc_pharmacy/models/stock/stock_adjustment.py +4 -4
  317. edc_pharmacy/models/stock/stock_request.py +2 -2
  318. edc_pharmacy/models/stock/stock_request_item.py +2 -2
  319. edc_pharmacy/models/stock/stock_transfer.py +3 -3
  320. edc_pharmacy/models/stock/stock_transfer_item.py +2 -2
  321. edc_pharmacy/models/stock/storage_bin.py +3 -4
  322. edc_pharmacy/models/stock/storage_bin_item.py +2 -2
  323. edc_pharmacy/models/stock/supplier.py +3 -4
  324. edc_pharmacy/models/storage/box.py +2 -2
  325. edc_pharmacy/models/storage/items/container_model_mixin.py +3 -4
  326. edc_pharmacy/models/storage/items/pill_bottle_model_mixin.py +2 -2
  327. edc_pharmacy/models/storage/items/subject_pill_bottle.py +1 -1
  328. edc_pharmacy/models/storage/room.py +2 -2
  329. edc_pharmacy/models/storage/shelf.py +2 -2
  330. edc_pharmacy/models/storage/utils.py +1 -1
  331. edc_pharmacy/prescribe/create_prescription.py +3 -3
  332. edc_pharmacy/utils/allocate_stock.py +2 -3
  333. edc_pharmacy/utils/confirm_stock.py +3 -4
  334. edc_pharmacy/utils/confirm_stock_at_site.py +4 -5
  335. edc_pharmacy/utils/dispense.py +3 -4
  336. edc_pharmacy/utils/process_repack_request.py +4 -5
  337. edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -3
  338. edc_pharmacy/utils/transfer_stock.py +2 -3
  339. edc_pharmacy/views/add_to_storage_bin_view.py +2 -2
  340. edc_pharmacy/views/allocate_to_subject_view.py +2 -2
  341. edc_pharmacy/views/confirmation_at_site_view.py +6 -9
  342. edc_pharmacy/views/dispense_view.py +2 -2
  343. edc_pharmacy/views/move_to_storage_bin_view.py +2 -3
  344. edc_pharmacy/views/print_labels_view.py +2 -2
  345. edc_prn/admin_site.py +5 -0
  346. edc_prn/prn.py +10 -11
  347. edc_prn/urls.py +11 -0
  348. edc_protocol/research_protocol_config.py +2 -3
  349. edc_protocol_incident/action_items.py +4 -4
  350. edc_protocol_incident/auths.py +27 -20
  351. edc_protocol_incident/migrations/0001_initial.py +7 -7
  352. edc_protocol_incident/migrations/0001_squashed_0015_auto_20220927_0401.py +13 -13
  353. edc_protocol_incident/migrations/0005_protocolincident_historicalprotocolincident_and_more.py +7 -7
  354. edc_protocol_incident/migrations/0024_alter_actionsrequired_extra_value_and_more.py +625 -0
  355. edc_protocol_incident/migrations/0025_alter_historicalprotocoldeviationviolation_report_datetime_and_more.py +42 -0
  356. edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +18 -11
  357. edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +26 -11
  358. edc_pylabels/actions.py +3 -5
  359. edc_pylabels/auths.py +6 -1
  360. edc_pylabels/migrations/0002_alter_label_options_label_created_and_more.py +3 -7
  361. edc_pylabels/migrations/0005_labelconfiguration_delete_label_and_more.py +3 -3
  362. edc_pylabels/migrations/0013_alter_labelconfiguration_device_created_and_more.py +49 -0
  363. edc_qareports/auths.py +11 -7
  364. edc_qareports/migrations/0001_initial.py +4 -5
  365. edc_qareports/migrations/0005_edcpermissions.py +3 -3
  366. edc_qareports/migrations/0006_qareportlog.py +2 -3
  367. edc_qareports/migrations/0019_alter_edcpermissions_device_created_and_more.py +102 -0
  368. edc_qareports/migrations/0020_alter_note_report_datetime_and_more.py +24 -0
  369. edc_qareports/model_mixins/note_model_mixin.py +7 -4
  370. edc_qareports/model_mixins/on_study_missing_values_model_mixin.py +4 -4
  371. edc_qareports/model_mixins/qa_report_model_mixin.py +2 -3
  372. edc_qareports/models/note.py +4 -4
  373. edc_qareports/models/qa_reports_log.py +2 -3
  374. edc_randomization/admin.py +30 -24
  375. edc_randomization/auths.py +12 -7
  376. edc_randomization/decorators.py +1 -1
  377. edc_randomization/migrations/0001_initial.py +3 -2
  378. edc_randomization/migrations/0002_historicalrandomizationlist.py +3 -2
  379. edc_randomization/migrations/0009_edcpermissions.py +3 -2
  380. edc_randomization/migrations/0014_alter_edcpermissions_device_created_and_more.py +141 -0
  381. edc_randomization/model_mixins.py +9 -9
  382. edc_randomization/randomizer.py +22 -20
  383. edc_randomization/utils.py +19 -18
  384. edc_refusal/auths.py +7 -2
  385. edc_refusal/migrations/0001_initial.py +4 -4
  386. edc_refusal/migrations/0002_historicalsubjectrefusal.py +4 -4
  387. edc_refusal/migrations/0012_alter_historicalsubjectrefusal_comment_and_more.py +122 -0
  388. edc_refusal/migrations/0013_alter_historicalsubjectrefusal_report_datetime_and_more.py +28 -0
  389. edc_refusal/model_mixins.py +4 -4
  390. edc_registration/auths.py +28 -23
  391. edc_registration/migrations/0002_auto_20161127_2226.py +3 -4
  392. edc_registration/migrations/0005_auto_20170111_1809.py +4 -2
  393. edc_registration/migrations/0016_historicalregisteredsubject.py +3 -2
  394. edc_registration/migrations/0017_auto_20190305_0123.py +5 -12
  395. edc_registration/migrations/0033_alter_historicalregisteredsubject_additional_key_and_more.py +302 -0
  396. edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +15 -7
  397. edc_registration/models/registered_subject.py +28 -27
  398. edc_reportable/age_evaluator.py +4 -2
  399. edc_reportable/formula.py +5 -5
  400. edc_reportable/migrations/0001_initial.py +7 -7
  401. edc_reportable/migrations/0003_referencerangecollection_grade1_and_more.py +3 -3
  402. edc_reportable/migrations/0004_alter_referencerangecollection_grade3_and_more.py +5 -5
  403. edc_reportable/migrations/0006_alter_gradingdata_revision_and_more.py +5 -6
  404. edc_reportable/migrations/0007_alter_gradingdata_age_phrase_and_more.py +509 -0
  405. edc_reportable/models/normal_data.py +4 -5
  406. edc_reportable/models/reference_model_mixins.py +10 -11
  407. edc_reportable/models/reference_range_collection.py +12 -13
  408. edc_reportable/post_migrate_signals.py +1 -1
  409. edc_reportable/utils/convert_units.py +11 -45
  410. edc_reportable/utils/get_normal_data_or_raise.py +2 -2
  411. edc_reportable/utils/get_reference_range_collection.py +2 -3
  412. edc_reportable/utils/load_data.py +4 -4
  413. edc_reportable/utils/update_grading_data.py +5 -5
  414. edc_review_dashboard/auths.py +23 -18
  415. edc_review_dashboard/migrations/0001_initial.py +3 -2
  416. edc_review_dashboard/migrations/0006_alter_edcpermissions_device_created_and_more.py +49 -0
  417. edc_screening/age_evaluator.py +6 -6
  418. edc_screening/auths.py +35 -30
  419. edc_screening/eligibility.py +1 -1
  420. edc_screening/gender_evaluator.py +1 -1
  421. edc_screening/migrations/0001_initial.py +3 -2
  422. edc_screening/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  423. edc_screening/model_mixins/eligibility_model_mixin.py +3 -6
  424. edc_screening/model_mixins/screening_fields_model_mixin.py +6 -8
  425. edc_screening/model_mixins/screening_methods_model_mixin.py +1 -1
  426. edc_screening/screening_eligibility.py +2 -4
  427. edc_screening/utils.py +9 -9
  428. edc_search/generate_slug.py +26 -0
  429. edc_search/model_mixins.py +10 -22
  430. edc_sites/auths.py +8 -3
  431. edc_sites/migrations/0007_edcpermissions.py +3 -2
  432. edc_sites/migrations/0010_alter_edcpermissions_device_created_and_more.py +69 -0
  433. edc_sites/model_mixins/site_model_mixin.py +2 -2
  434. edc_sites/site.py +5 -5
  435. edc_sites/system_checks.py +1 -1
  436. edc_subject_dashboard/auths.py +27 -22
  437. edc_subject_dashboard/migrations/0001_initial.py +3 -2
  438. edc_subject_dashboard/migrations/0005_alter_edcpermissions_device_created_and_more.py +49 -0
  439. edc_subject_dashboard/requisition_report.py +6 -4
  440. edc_subject_dashboard/requisition_verifier.py +6 -6
  441. edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +2 -2
  442. edc_subject_dashboard/view_mixins/subject_visit_view_mixin.py +7 -8
  443. edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +3 -2
  444. edc_subject_dashboard/view_utils/timepoint_status_button.py +2 -2
  445. edc_timepoint/apps.py +0 -21
  446. edc_timepoint/model_mixins.py +22 -20
  447. edc_transfer/model_mixins.py +4 -4
  448. edc_transfer/modeladmin_mixins.py +1 -1
  449. edc_unblinding/auths.py +9 -4
  450. edc_unblinding/migrations/0001_initial.py +13 -13
  451. edc_unblinding/migrations/0014_alter_historicalunblindingrequest_action_identifier_and_more.py +291 -0
  452. edc_unblinding/migrations/0015_alter_historicalunblindingrequest_report_datetime_and_more.py +45 -0
  453. edc_unblinding/models/unblinding_request.py +2 -2
  454. edc_unblinding/models/unblinding_review.py +3 -3
  455. edc_utils/__init__.py +3 -1
  456. edc_utils/age.py +10 -16
  457. edc_utils/show_urls.py +29 -2
  458. edc_visit_schedule/auths.py +6 -1
  459. edc_visit_schedule/migrations/0001_initial.py +3 -3
  460. edc_visit_schedule/migrations/0002_auto_20190305_0123.py +3 -6
  461. edc_visit_schedule/migrations/0003_historicalvisitschedule_visitschedule.py +5 -4
  462. edc_visit_schedule/migrations/0015_historicalonschedule_offschedule_onschedule.py +10 -10
  463. edc_visit_schedule/migrations/0019_alter_historicalonschedule_device_created_and_more.py +229 -0
  464. edc_visit_schedule/migrations/0020_alter_historicalonschedule_onschedule_datetime_and_more.py +65 -0
  465. edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +5 -4
  466. edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +5 -4
  467. edc_visit_schedule/model_mixins/visit_schedule/visit_code_fields_model_mixin.py +1 -1
  468. edc_visit_schedule/models/subject_schedule_history.py +6 -6
  469. edc_visit_schedule/schedule/visit_collection.py +1 -1
  470. edc_visit_schedule/site_visit_schedules.py +2 -2
  471. edc_visit_schedule/subject_schedule.py +5 -4
  472. edc_visit_schedule/view_mixins.py +2 -3
  473. edc_visit_schedule/visit/visit.py +3 -2
  474. edc_visit_tracking/migrations/0004_subjectvisit_subjectvisitmissedreasons_extra_value_and_more.py +13 -13
  475. edc_visit_tracking/migrations/0009_alter_historicalsubjectvisit_comments_and_more.py +450 -0
  476. edc_visit_tracking/migrations/0010_alter_historicalsubjectvisit_report_datetime_and_more.py +68 -0
  477. edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +3 -3
  478. edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +2 -2
  479. edc_visit_tracking/model_mixins/requisitions/visit_tracking_requisition_model_mixin.py +2 -2
  480. edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +2 -2
  481. edc_visit_tracking/model_mixins/visit_model_mixin/caretaker_fields_mixin.py +2 -3
  482. edc_visit_tracking/model_mixins/visit_model_mixin/previous_visit_model_mixin.py +1 -1
  483. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_fields_mixin.py +8 -11
  484. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +1 -1
  485. edc_visit_tracking/models/signals.py +3 -3
  486. edc_visit_tracking/models/subject_visit.py +1 -1
  487. edc_vitals/calculators/bmi.py +7 -5
  488. edc_vitals/utils.py +1 -1
  489. edc_form_label/models.py +0 -0
  490. edc_search/constants.py +0 -1
  491. edc_search/models.py +0 -0
  492. edc_search/search_slug.py +0 -50
  493. edc_search/updater.py +0 -30
  494. edc_search/wsgi.py +0 -7
  495. {clinicedc-2.0.6.dist-info → clinicedc-2.0.8.dist-info}/licenses/LICENSE +0 -0
@@ -20,7 +20,6 @@ if TYPE_CHECKING:
20
20
 
21
21
 
22
22
  class ReferenceRangeCollection(BaseUuidModel):
23
-
24
23
  name = models.CharField(max_length=50, unique=True)
25
24
 
26
25
  grade1 = models.BooleanField(default=False)
@@ -60,13 +59,13 @@ class ReferenceRangeCollection(BaseUuidModel):
60
59
 
61
60
  def get_grade(
62
61
  self,
63
- value: float | int = None,
64
- label: str = None,
65
- units: str = None,
62
+ value: float | int | None = None,
63
+ label: str | None = None,
64
+ units: str | None = None,
66
65
  subject_identifier: str | None = None,
67
- report_datetime: datetime = None,
68
- gender: str = None,
69
- dob: date = None,
66
+ report_datetime: datetime | None = None,
67
+ gender: str | None = None,
68
+ dob: date | None = None,
70
69
  age_units: str | None = None,
71
70
  site: Site | None = None,
72
71
  ) -> tuple[GradingData | None, str | None]:
@@ -89,13 +88,13 @@ class ReferenceRangeCollection(BaseUuidModel):
89
88
 
90
89
  def is_normal(
91
90
  self,
92
- value: float | int = None,
93
- label: str = None,
94
- units: str = None,
91
+ value: float | int | None = None,
92
+ label: str | None = None,
93
+ units: str | None = None,
95
94
  subject_identifier: str | None = None,
96
- report_datetime: datetime = None,
97
- gender: str = None,
98
- dob: date = None,
95
+ report_datetime: datetime | None = None,
96
+ gender: str | None = None,
97
+ dob: date | None = None,
99
98
  age_units: str | None = None,
100
99
  site: Site | None = None,
101
100
  ) -> tuple[bool, NormalData]:
@@ -19,7 +19,7 @@ def load_mw():
19
19
  model_cls.objects.get_or_create(label=label, mw=mw)
20
20
 
21
21
 
22
- def post_migrate_load_reference_ranges(sender=None, **kwargs): # noqa
22
+ def post_migrate_load_reference_ranges(sender=None, **kwargs):
23
23
  sys.stdout.write(style.MIGRATE_HEADING("Loading reference ranges (reportables):\n"))
24
24
  load_mw()
25
25
  load_all_reference_ranges()
@@ -20,18 +20,16 @@ __all__ = ["convert_units"]
20
20
  def get_mw(label):
21
21
  try:
22
22
  molecular_weight = molecular_weight_model_cls().objects.get(label=label)
23
- except ObjectDoesNotExist:
23
+ except ObjectDoesNotExist as e:
24
24
  raise ConversionNotHandled(
25
25
  f"Conversion not handled. Molecular weight not found for {label}."
26
- )
26
+ ) from e
27
27
  else:
28
28
  mw = molecular_weight.mw
29
29
  return mw
30
30
 
31
31
 
32
- def micromoles_per_liter_to(
33
- *, label: str = None, value: float | int = None, units_to: str = None
34
- ) -> dict:
32
+ def micromoles_per_liter_to(*, label: str, value: float | int, units_to: str) -> dict:
35
33
  if units_to == MICROMOLES_PER_LITER:
36
34
  return {MICROMOLES_PER_LITER: float(value)}
37
35
  if units_to == MILLIMOLES_PER_LITER:
@@ -44,8 +42,8 @@ def micromoles_per_liter_to(
44
42
 
45
43
 
46
44
  def milligrams_per_deciliter_to(
47
- *, label: str = None, value: float | int = None, units_to: str = None
48
- ) -> dict[str:float]:
45
+ *, label: str, value: float | int, units_to: str
46
+ ) -> dict[str, float]:
49
47
  if units_to == MILLIGRAMS_PER_DECILITER:
50
48
  return {MILLIGRAMS_PER_DECILITER: float(value)}
51
49
  if units_to == MILLIMOLES_PER_LITER:
@@ -63,10 +61,10 @@ class UnitsConverter:
63
61
  def __init__(
64
62
  self,
65
63
  *,
66
- label: str = None,
67
- value: int | float | None = None,
68
- units_from: str | None = None,
69
- units_to: str | None = None,
64
+ label: str,
65
+ value: int | float,
66
+ units_from: str,
67
+ units_to: str,
70
68
  places: int | None = None,
71
69
  ):
72
70
  self.label = label
@@ -97,7 +95,7 @@ class UnitsConverter:
97
95
  f"Conversion not handled. Tried {self.label} from {self.units_from} "
98
96
  f"to {self.units_to}. "
99
97
  f"Got {e} when rounding {converted_value} to {self.places} places."
100
- )
98
+ ) from e
101
99
  return converted_value
102
100
 
103
101
  def from_milligrams_per_deciliter(self) -> float | int:
@@ -106,14 +104,6 @@ class UnitsConverter:
106
104
  label=self.label, value=float(self.value), units_to=self.units_to
107
105
  )[self.units_to]
108
106
  return self.value
109
- # converted_value = None
110
- # if self.units_to == MILLIMOLES_PER_LITER:
111
- # converted_value = (float(self.value) * 10.00) / self.get_mw()
112
- # elif self.units_to == MICROMOLES_PER_LITER:
113
- # converted_value = (float(self.value) * 10.00**3) / self.get_mw()
114
- # elif self.units_to == GRAMS_PER_LITER:
115
- # converted_value = float(self.value) / 100.00
116
- # return converted_value
117
107
 
118
108
  def from_grams_per_liter(self) -> float | int:
119
109
  if self.units_to != GRAMS_PER_LITER:
@@ -123,14 +113,6 @@ class UnitsConverter:
123
113
  units_to=self.units_to,
124
114
  )[self.units_to]
125
115
  return self.value
126
- # converted_value = None
127
- # if self.units_to == MILLIMOLES_PER_LITER:
128
- # converted_value = (self.value * 1000.00) / self.get_mw()
129
- # elif self.units_to == MICROMOLES_PER_LITER:
130
- # converted_value = (self.value * 10.00**6) / self.get_mw()
131
- # elif self.units_to == MILLIGRAMS_PER_DECILITER:
132
- # converted_value = float(self.value) * 100.00
133
- # return converted_value
134
116
 
135
117
  def from_millimoles_per_liter(self) -> float | int:
136
118
  if self.units_to != MILLIMOLES_PER_LITER:
@@ -138,14 +120,6 @@ class UnitsConverter:
138
120
  label=self.label, value=self.value / 1000, units_to=self.units_to
139
121
  )[self.units_to]
140
122
  return self.value
141
- # converted_value = None
142
- # if self.units_to == MICROMOLES_PER_LITER:
143
- # converted_value = self.value * 1000.00
144
- # elif self.units_to == GRAMS_PER_LITER:
145
- # converted_value = (self.value * self.get_mw()) / 1000.00
146
- # elif self.units_to == MILLIGRAMS_PER_DECILITER:
147
- # converted_value = (self.value * self.get_mw()) / 10.00
148
- # return converted_value
149
123
 
150
124
  def from_micromoles_per_liter(self):
151
125
  if self.units_to != MICROMOLES_PER_LITER:
@@ -153,14 +127,6 @@ class UnitsConverter:
153
127
  label=self.label, value=self.value, units_to=self.units_to
154
128
  )[self.units_to]
155
129
  return self.value
156
- # converted_value = None
157
- # if self.units_to == MILLIMOLES_PER_LITER:
158
- # converted_value = self.value / 1000.00
159
- # elif self.units_to == GRAMS_PER_LITER:
160
- # converted_value = (self.value * self.get_mw()) / 10**6
161
- # elif self.units_to == MILLIGRAMS_PER_DECILITER:
162
- # converted_value = (self.value * self.get_mw()) / 10**4
163
- # return converted_value
164
130
 
165
131
  def get_converted_value(self) -> int | float:
166
132
  converted_value = None
@@ -182,7 +148,7 @@ class UnitsConverter:
182
148
 
183
149
  def convert_units(
184
150
  *,
185
- label: str = None,
151
+ label: str | None = None,
186
152
  value: int | float | None = None,
187
153
  units_from: str | None = None,
188
154
  units_to: str | None = None,
@@ -5,10 +5,10 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
7
7
  from django.db.models import Q
8
+ from django.utils import timezone
8
9
 
9
10
  from edc_model_to_dataframe.constants import SYSTEM_COLUMNS
10
11
  from edc_utils import age as get_age
11
- from edc_utils import get_utcnow
12
12
 
13
13
  from ..exceptions import NotEvaluated
14
14
  from .convert_units import convert_units
@@ -135,7 +135,7 @@ def create_obj_for_new_units_or_raise(
135
135
  )
136
136
  opts["units"] = units
137
137
  opts["auto_created"] = True
138
- opts["created"] = get_utcnow()
138
+ opts["created"] = timezone.now()
139
139
  opts["modified"] = opts["created"]
140
140
  break
141
141
  if opts:
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import contextlib
3
4
  from typing import TYPE_CHECKING
4
5
 
5
6
  from django.core.exceptions import ObjectDoesNotExist
@@ -21,10 +22,8 @@ def get_reference_range_collection(obj) -> ReferenceRangeCollection:
21
22
  name = obj.requisition.panel_object.reference_range_collection_name
22
23
  except AttributeError:
23
24
  name = obj.panel_object.reference_range_collection_name
24
- try:
25
+ with contextlib.suppress(ObjectDoesNotExist):
25
26
  reference_range_collection = reference_range_colllection_model_cls().objects.get(
26
27
  name=name
27
28
  )
28
- except ObjectDoesNotExist:
29
- pass
30
29
  return reference_range_collection
@@ -58,10 +58,10 @@ def load_all_reference_ranges() -> None:
58
58
 
59
59
  def load_reference_ranges(
60
60
  collection_name: str,
61
- normal_data: dict[str, list[Formula]] = None,
62
- grading_data: dict[str, list[Formula]] = None,
63
- reportable_grades: list[int] = None,
64
- reportable_grades_exceptions: dict[str, list[int]] = None,
61
+ normal_data: dict[str, list[Formula]],
62
+ grading_data: dict[str, list[Formula]],
63
+ reportable_grades: list[int] | None = None,
64
+ reportable_grades_exceptions: dict[str, list[int]] | None = None,
65
65
  keep_existing: bool | None = None,
66
66
  create_missing_normal: bool | None = None,
67
67
  ) -> ReferenceRangeCollection:
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import sys
3
4
  from typing import TYPE_CHECKING
4
5
 
5
6
  from dateutil.relativedelta import relativedelta
6
7
  from django.core.exceptions import ObjectDoesNotExist
7
-
8
- from edc_utils import get_utcnow
8
+ from django.utils import timezone
9
9
 
10
10
  from ..exceptions import NotEvaluated
11
11
  from ..formula import Formula
@@ -55,7 +55,7 @@ def update_grading_data(
55
55
  value=value,
56
56
  units=formula_opts.get("units"),
57
57
  gender=gender,
58
- dob=get_utcnow()
58
+ dob=timezone.now()
59
59
  - relativedelta(
60
60
  **{
61
61
  age_opts.get("age_units"): age_opts.get(
@@ -63,12 +63,12 @@ def update_grading_data(
63
63
  )
64
64
  }
65
65
  ),
66
- report_datetime=get_utcnow(),
66
+ report_datetime=timezone.now(),
67
67
  age_units=age_opts.get("age_units"),
68
68
  create_missing_normal=create_missing_normal,
69
69
  )
70
70
  except NotEvaluated as e:
71
- print(e)
71
+ sys.stdout.write(f"{e}\n")
72
72
 
73
73
 
74
74
  def get_reportable_grades(
@@ -10,23 +10,28 @@ from edc_auth.utils import remove_default_model_permissions_from_edc_permissions
10
10
 
11
11
  REVIEW = "REVIEW"
12
12
 
13
- site_auths.add_post_update_func(
14
- "edc_review_dashboard", remove_default_model_permissions_from_edc_permissions
15
- )
16
13
 
17
- site_auths.add_custom_permissions_tuples(
18
- model="edc_review_dashboard.edcpermissions",
19
- codename_tuples=[
20
- (
21
- "edc_review_dashboard.view_subject_review_listboard",
22
- "Can access subject review listboard",
23
- )
24
- ],
25
- )
26
- site_auths.add_group("edc_review_dashboard.view_subject_review_listboard", name=REVIEW)
14
+ def update_site_auths():
15
+ site_auths.add_post_update_func(
16
+ "edc_review_dashboard", remove_default_model_permissions_from_edc_permissions
17
+ )
18
+
19
+ site_auths.add_custom_permissions_tuples(
20
+ model="edc_review_dashboard.edcpermissions",
21
+ codename_tuples=[
22
+ (
23
+ "edc_review_dashboard.view_subject_review_listboard",
24
+ "Can access subject review listboard",
25
+ )
26
+ ],
27
+ )
28
+ site_auths.add_group("edc_review_dashboard.view_subject_review_listboard", name=REVIEW)
29
+
30
+ site_auths.update_role(REVIEW, name=AUDITOR_ROLE)
31
+ site_auths.update_role(REVIEW, name=TMG_ROLE)
32
+ site_auths.update_role(REVIEW, name=CLINICIAN_ROLE)
33
+ site_auths.update_role(REVIEW, name=CLINICIAN_SUPER_ROLE)
34
+ site_auths.update_role(REVIEW, name=NURSE_ROLE)
35
+
27
36
 
28
- site_auths.update_role(REVIEW, name=AUDITOR_ROLE)
29
- site_auths.update_role(REVIEW, name=TMG_ROLE)
30
- site_auths.update_role(REVIEW, name=CLINICIAN_ROLE)
31
- site_auths.update_role(REVIEW, name=CLINICIAN_SUPER_ROLE)
32
- site_auths.update_role(REVIEW, name=NURSE_ROLE)
37
+ update_site_auths()
@@ -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=django_audit_fields.models.audit_model_mixin.utcnow,
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=django_audit_fields.models.audit_model_mixin.utcnow,
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_review_dashboard", "0005_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
+ ]
@@ -1,18 +1,18 @@
1
1
  from dateutil.relativedelta import relativedelta
2
+ from django.utils import timezone
2
3
  from django.utils.timezone import localtime
3
4
 
4
5
  from edc_reportable.age_evaluator import AgeEvaluator as ReportableAgeEvaluator
5
6
  from edc_reportable.exceptions import ValueBoundryError
6
- from edc_utils.date import get_utcnow
7
7
 
8
8
 
9
9
  class AgeEvaluator(ReportableAgeEvaluator):
10
10
  def __init__(self, **kwargs) -> None:
11
- self.reasons_ineligible: str | None = None
11
+ self.reasons_ineligible: str = ""
12
12
  super().__init__(**kwargs)
13
13
 
14
14
  def eligible(self, age: int | None = None) -> bool:
15
- self.reasons_ineligible = None
15
+ self.reasons_ineligible = ""
16
16
  eligible = False
17
17
  if age:
18
18
  try:
@@ -26,10 +26,10 @@ class AgeEvaluator(ReportableAgeEvaluator):
26
26
  return eligible
27
27
 
28
28
  def in_bounds_or_raise(self, age: int = None, **kwargs):
29
- self.reasons_ineligible = None
30
- dob = localtime(get_utcnow() - relativedelta(years=age)).date()
29
+ self.reasons_ineligible = ""
30
+ dob = localtime(timezone.now() - relativedelta(years=age)).date()
31
31
  age_units = "years"
32
- report_datetime = localtime(get_utcnow())
32
+ report_datetime = localtime(timezone.now())
33
33
  return super().in_bounds_or_raise(
34
34
  dob=dob, report_datetime=report_datetime, age_units=age_units
35
35
  )
edc_screening/auths.py CHANGED
@@ -9,38 +9,43 @@ from edc_auth.utils import remove_default_model_permissions_from_edc_permissions
9
9
 
10
10
  from .auth_objects import SCREENING, SCREENING_ROLE, SCREENING_SUPER, SCREENING_VIEW
11
11
 
12
- site_auths.add_post_update_func(
13
- "edc_screening", remove_default_model_permissions_from_edc_permissions
14
- )
15
12
 
16
- site_auths.add_custom_permissions_tuples(
17
- model="edc_screening.edcpermissions",
18
- codename_tuples=(
19
- ("edc_screening.view_screening_listboard", "Can access Screening listboard"),
20
- ("edc_screening.nav_screening_section", "Can access screening section"),
21
- ),
22
- )
13
+ def update_site_auths() -> None:
14
+ site_auths.add_post_update_func(
15
+ "edc_screening", remove_default_model_permissions_from_edc_permissions
16
+ )
23
17
 
24
- site_auths.add_group(
25
- "edc_screening.view_screening_listboard",
26
- "edc_screening.nav_screening_section",
27
- name=SCREENING,
28
- )
18
+ site_auths.add_custom_permissions_tuples(
19
+ model="edc_screening.edcpermissions",
20
+ codename_tuples=(
21
+ ("edc_screening.view_screening_listboard", "Can access Screening listboard"),
22
+ ("edc_screening.nav_screening_section", "Can access screening section"),
23
+ ),
24
+ )
29
25
 
30
- site_auths.add_group(
31
- "edc_screening.view_screening_listboard",
32
- "edc_screening.nav_screening_section",
33
- name=SCREENING_SUPER,
34
- )
26
+ site_auths.add_group(
27
+ "edc_screening.view_screening_listboard",
28
+ "edc_screening.nav_screening_section",
29
+ name=SCREENING,
30
+ )
31
+
32
+ site_auths.add_group(
33
+ "edc_screening.view_screening_listboard",
34
+ "edc_screening.nav_screening_section",
35
+ name=SCREENING_SUPER,
36
+ )
37
+
38
+ site_auths.add_group(
39
+ "edc_screening.view_screening_listboard",
40
+ "edc_screening.nav_screening_section",
41
+ name=SCREENING_VIEW,
42
+ )
43
+
44
+ site_auths.add_role(SCREENING, name=SCREENING_ROLE)
45
+ site_auths.update_role(SCREENING, name=CLINICIAN_ROLE)
46
+ site_auths.update_role(SCREENING, name=NURSE_ROLE)
47
+ site_auths.update_role(SCREENING_SUPER, name=CLINICIAN_SUPER_ROLE)
48
+ site_auths.update_role(SCREENING_VIEW, name=AUDITOR_ROLE)
35
49
 
36
- site_auths.add_group(
37
- "edc_screening.view_screening_listboard",
38
- "edc_screening.nav_screening_section",
39
- name=SCREENING_VIEW,
40
- )
41
50
 
42
- site_auths.add_role(SCREENING, name=SCREENING_ROLE)
43
- site_auths.update_role(SCREENING, name=CLINICIAN_ROLE)
44
- site_auths.update_role(SCREENING, name=NURSE_ROLE)
45
- site_auths.update_role(SCREENING_SUPER, name=CLINICIAN_SUPER_ROLE)
46
- site_auths.update_role(SCREENING_VIEW, name=AUDITOR_ROLE)
51
+ update_site_auths()
@@ -45,7 +45,7 @@ class Eligibility:
45
45
  self.eligible = all([v for v in self.criteria.values()])
46
46
 
47
47
  if self.eligible:
48
- self.reasons_ineligible = None
48
+ self.reasons_ineligible = ""
49
49
  else:
50
50
  self.reasons_ineligible = {k: v for k, v in self.criteria.items() if not v}
51
51
  for k, v in self.criteria.items():
@@ -6,7 +6,7 @@ class GenderEvaluator:
6
6
 
7
7
  def __init__(self, gender=None, **kwargs) -> None: # noqa
8
8
  self.eligible = False
9
- self.reasons_ineligible = None
9
+ self.reasons_ineligible = ""
10
10
  if gender in self.eligible_gender:
11
11
  self.eligible = True
12
12
  else:
@@ -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=django_audit_fields.models.audit_model_mixin.utcnow,
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=django_audit_fields.models.audit_model_mixin.utcnow,
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_screening", "0004_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
+ ]
@@ -1,6 +1,5 @@
1
1
  from django.db import models
2
-
3
- from edc_utils import get_utcnow
2
+ from django.utils import timezone
4
3
 
5
4
  from ..screening_eligibility import ScreeningEligibility
6
5
 
@@ -9,7 +8,7 @@ class EligibilityFieldsModelMixin(models.Model):
9
8
  eligible = models.BooleanField(default=False)
10
9
 
11
10
  reasons_ineligible = models.TextField(
12
- verbose_name="Reason not eligible", max_length=150, null=True
11
+ verbose_name="Reason not eligible", max_length=150, default=""
13
12
  )
14
13
 
15
14
  eligibility_datetime = models.DateTimeField(
@@ -46,13 +45,11 @@ class EligibilityModelMixin(EligibilityFieldsModelMixin, models.Model):
46
45
  """
47
46
  # if self.eligibility_cls:
48
47
  self.eligibility_cls(model_obj=self)
49
- # self.eligible = eligibility_obj.is_eligible
50
- # self.reasons_ineligible = eligibility_obj.reasons_ineligible
51
48
  if not self.id:
52
49
  self.screening_identifier = self.identifier_cls().identifier
53
50
  if self.eligible:
54
51
  self.eligibility_datetime = self.get_report_datetime_for_eligibility_datetime()
55
- self.real_eligibility_datetime = get_utcnow()
52
+ self.real_eligibility_datetime = timezone.now()
56
53
  else:
57
54
  self.eligibility_datetime = None
58
55
  self.real_eligibility_datetime = None