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
@@ -6,7 +6,7 @@ from django.db import migrations, models
6
6
 
7
7
  import edc_model_fields.fields.hostname_modification_field
8
8
  import edc_model_fields.fields.userfield
9
- import edc_utils
9
+ import django.utils.timezone
10
10
 
11
11
 
12
12
  class Migration(migrations.Migration):
@@ -16,7 +16,7 @@ class Migration(migrations.Migration):
16
16
  migrations.AlterField(
17
17
  model_name="historicalidentifierhistory",
18
18
  name="created",
19
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
19
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
20
20
  ),
21
21
  migrations.AlterField(
22
22
  model_name="historicalidentifierhistory",
@@ -40,7 +40,7 @@ class Migration(migrations.Migration):
40
40
  migrations.AlterField(
41
41
  model_name="historicalidentifierhistory",
42
42
  name="modified",
43
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
43
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
44
44
  ),
45
45
  migrations.AlterField(
46
46
  model_name="historicalidentifierhistory",
@@ -59,7 +59,7 @@ class Migration(migrations.Migration):
59
59
  migrations.AlterField(
60
60
  model_name="historicalidentifiertracker",
61
61
  name="created",
62
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
62
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
63
63
  ),
64
64
  migrations.AlterField(
65
65
  model_name="historicalidentifiertracker",
@@ -83,7 +83,7 @@ class Migration(migrations.Migration):
83
83
  migrations.AlterField(
84
84
  model_name="historicalidentifiertracker",
85
85
  name="modified",
86
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
86
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
87
87
  ),
88
88
  migrations.AlterField(
89
89
  model_name="historicalidentifiertracker",
@@ -102,7 +102,7 @@ class Migration(migrations.Migration):
102
102
  migrations.AlterField(
103
103
  model_name="historicalsubjectidentifier",
104
104
  name="created",
105
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
105
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
106
106
  ),
107
107
  migrations.AlterField(
108
108
  model_name="historicalsubjectidentifier",
@@ -126,7 +126,7 @@ class Migration(migrations.Migration):
126
126
  migrations.AlterField(
127
127
  model_name="historicalsubjectidentifier",
128
128
  name="modified",
129
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
129
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
130
130
  ),
131
131
  migrations.AlterField(
132
132
  model_name="historicalsubjectidentifier",
@@ -145,7 +145,7 @@ class Migration(migrations.Migration):
145
145
  migrations.AlterField(
146
146
  model_name="identifierhistory",
147
147
  name="created",
148
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
148
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
149
149
  ),
150
150
  migrations.AlterField(
151
151
  model_name="identifierhistory",
@@ -169,7 +169,7 @@ class Migration(migrations.Migration):
169
169
  migrations.AlterField(
170
170
  model_name="identifierhistory",
171
171
  name="modified",
172
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
172
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
173
173
  ),
174
174
  migrations.AlterField(
175
175
  model_name="identifierhistory",
@@ -188,7 +188,7 @@ class Migration(migrations.Migration):
188
188
  migrations.AlterField(
189
189
  model_name="identifiermodel",
190
190
  name="created",
191
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
191
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
192
192
  ),
193
193
  migrations.AlterField(
194
194
  model_name="identifiermodel",
@@ -212,7 +212,7 @@ class Migration(migrations.Migration):
212
212
  migrations.AlterField(
213
213
  model_name="identifiermodel",
214
214
  name="modified",
215
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
215
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
216
216
  ),
217
217
  migrations.AlterField(
218
218
  model_name="identifiermodel",
@@ -231,7 +231,7 @@ class Migration(migrations.Migration):
231
231
  migrations.AlterField(
232
232
  model_name="identifiertracker",
233
233
  name="created",
234
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
234
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
235
235
  ),
236
236
  migrations.AlterField(
237
237
  model_name="identifiertracker",
@@ -255,7 +255,7 @@ class Migration(migrations.Migration):
255
255
  migrations.AlterField(
256
256
  model_name="identifiertracker",
257
257
  name="modified",
258
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
258
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
259
259
  ),
260
260
  migrations.AlterField(
261
261
  model_name="identifiertracker",
@@ -274,7 +274,7 @@ class Migration(migrations.Migration):
274
274
  migrations.AlterField(
275
275
  model_name="sequence",
276
276
  name="created",
277
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
277
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
278
278
  ),
279
279
  migrations.AlterField(
280
280
  model_name="sequence",
@@ -298,7 +298,7 @@ class Migration(migrations.Migration):
298
298
  migrations.AlterField(
299
299
  model_name="sequence",
300
300
  name="modified",
301
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
301
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
302
302
  ),
303
303
  migrations.AlterField(
304
304
  model_name="sequence",
@@ -317,7 +317,7 @@ class Migration(migrations.Migration):
317
317
  migrations.AlterField(
318
318
  model_name="subjectidentifier",
319
319
  name="created",
320
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
320
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
321
321
  ),
322
322
  migrations.AlterField(
323
323
  model_name="subjectidentifier",
@@ -341,7 +341,7 @@ class Migration(migrations.Migration):
341
341
  migrations.AlterField(
342
342
  model_name="subjectidentifier",
343
343
  name="modified",
344
- field=models.DateTimeField(blank=True, default=edc_utils.date.get_utcnow),
344
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
345
345
  ),
346
346
  migrations.AlterField(
347
347
  model_name="subjectidentifier",
@@ -0,0 +1,79 @@
1
+ # Generated by Django 5.2.6 on 2025-09-17 15:50
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("edc_identifier", "0010_alter_identifiermodel_revision"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="identifiermodel",
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="identifiermodel",
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="identifiermodel",
29
+ name="identifier_prefix",
30
+ field=models.CharField(default="", max_length=25),
31
+ ),
32
+ migrations.AlterField(
33
+ model_name="identifiermodel",
34
+ name="identifier_type",
35
+ field=models.CharField(default="", max_length=100),
36
+ ),
37
+ migrations.AlterField(
38
+ model_name="identifiermodel",
39
+ name="linked_identifier",
40
+ field=models.CharField(default="", max_length=50),
41
+ ),
42
+ migrations.AlterField(
43
+ model_name="identifiermodel",
44
+ name="locale_created",
45
+ field=models.CharField(
46
+ blank=True,
47
+ default="",
48
+ help_text="Auto-updated by Modeladmin",
49
+ max_length=10,
50
+ verbose_name="Locale created",
51
+ ),
52
+ ),
53
+ migrations.AlterField(
54
+ model_name="identifiermodel",
55
+ name="locale_modified",
56
+ field=models.CharField(
57
+ blank=True,
58
+ default="",
59
+ help_text="Auto-updated by Modeladmin",
60
+ max_length=10,
61
+ verbose_name="Locale modified",
62
+ ),
63
+ ),
64
+ migrations.AlterField(
65
+ model_name="identifiermodel",
66
+ name="model",
67
+ field=models.CharField(default="", max_length=100),
68
+ ),
69
+ migrations.AlterField(
70
+ model_name="identifiermodel",
71
+ name="protocol_number",
72
+ field=models.CharField(default="", max_length=25),
73
+ ),
74
+ migrations.AlterField(
75
+ model_name="identifiermodel",
76
+ name="subject_identifier",
77
+ field=models.CharField(default="", max_length=50),
78
+ ),
79
+ ]
@@ -44,7 +44,7 @@ class SubjectIdentifierAdditionalFieldsModelMixin(models.Model):
44
44
  subject_identifier_aka = models.CharField(
45
45
  verbose_name="Subject Identifier a.k.a",
46
46
  max_length=50,
47
- null=True,
47
+ default="",
48
48
  editable=False,
49
49
  help_text="track a previously allocated identifier.",
50
50
  )
edc_identifier/models.py CHANGED
@@ -25,21 +25,21 @@ class IdentifierModel(SiteModelMixin, BaseUuidModel):
25
25
 
26
26
  name = models.CharField(max_length=100)
27
27
 
28
- subject_identifier = models.CharField(max_length=50, null=True)
28
+ subject_identifier = models.CharField(max_length=50, default="")
29
29
 
30
30
  sequence_number = models.IntegerField(default=1)
31
31
 
32
- linked_identifier = models.CharField(max_length=50, null=True)
32
+ linked_identifier = models.CharField(max_length=50, default="")
33
33
 
34
34
  device_id = models.IntegerField()
35
35
 
36
- protocol_number = models.CharField(max_length=25, null=True)
36
+ protocol_number = models.CharField(max_length=25, default="")
37
37
 
38
- model = models.CharField(max_length=100, null=True)
38
+ model = models.CharField(max_length=100, default="")
39
39
 
40
- identifier_type = models.CharField(max_length=100, null=True)
40
+ identifier_type = models.CharField(max_length=100, default="")
41
41
 
42
- identifier_prefix = models.CharField(max_length=25, null=True)
42
+ identifier_prefix = models.CharField(max_length=25, default="")
43
43
 
44
44
  objects = IdentifierModelManager()
45
45
 
@@ -51,9 +51,9 @@ class IdentifierModel(SiteModelMixin, BaseUuidModel):
51
51
 
52
52
  class Meta(BaseUuidModel.Meta):
53
53
  app_label = "edc_identifier"
54
- constraints = [
54
+ constraints = (
55
55
  UniqueConstraint(
56
56
  fields=["name", "identifier"], name="%(app_label)s_%(class)s_name_uniq"
57
- )
58
- ]
57
+ ),
58
+ )
59
59
  indexes = BaseUuidModel.Meta.indexes
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
16
16
  from .models import IdentifierModel
17
17
 
18
18
 
19
- class IdentifierMissingTemplateValue(Exception):
19
+ class IdentifierMissingTemplateValue(Exception): # noqa: N818
20
20
  pass
21
21
 
22
22
 
@@ -38,6 +38,7 @@ class ResearchIdentifier:
38
38
  identifier: str | None = None,
39
39
  ) -> None:
40
40
  self._identifier = None
41
+ self._sequence_number = None
41
42
  self.requesting_model = requesting_model
42
43
  if not self.requesting_model:
43
44
  raise IdentifierError("Invalid requesting_model. Got None")
@@ -121,10 +122,10 @@ class ResearchIdentifier:
121
122
  for key in keys:
122
123
  try:
123
124
  value = getattr(self, key)
124
- except AttributeError:
125
+ except AttributeError as e:
125
126
  raise IdentifierMissingTemplateValue(
126
127
  f"Required option not provided. Got '{key}'."
127
- )
128
+ ) from e
128
129
  else:
129
130
  if value:
130
131
  template_opts.update({key: value})
@@ -141,15 +142,15 @@ class ResearchIdentifier:
141
142
  @property
142
143
  def sequence_number(self) -> int:
143
144
  """Returns the next sequence number to use."""
144
- try:
145
- identifier_model = (
145
+ if self._sequence_number is None:
146
+ if identifier_model := (
146
147
  self.identifier_model_cls.objects.filter(
147
148
  name=self.label, device_id=self.device_id, site=self.site
148
149
  )
149
150
  .order_by("-sequence_number")
150
151
  .first()
151
- )
152
- sequence_number = identifier_model.sequence_number + 1
153
- except AttributeError:
154
- sequence_number = 1
155
- return sequence_number
152
+ ):
153
+ self._sequence_number = identifier_model.sequence_number + 1
154
+ else:
155
+ self._sequence_number = 1
156
+ return self._sequence_number
@@ -1,15 +1,18 @@
1
+ from __future__ import annotations
2
+
1
3
  from secrets import choice
2
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
3
5
 
4
6
  from django.apps import apps as django_apps
5
7
  from django.core.exceptions import ObjectDoesNotExist
6
8
  from django.db import models
7
9
  from django.utils import timezone
8
10
 
9
- from edc_utils import get_utcnow
10
-
11
11
  from .utils import convert_to_human_readable
12
12
 
13
+ if TYPE_CHECKING:
14
+ from edc_identifier.models import IdentifierModel
15
+
13
16
 
14
17
  class DuplicateIdentifierError(Exception):
15
18
  pass
@@ -83,7 +86,7 @@ class SimpleSequentialIdentifier:
83
86
  prefix: str | None = None
84
87
 
85
88
  def __init__(self):
86
- sequence: int = int(get_utcnow().timestamp())
89
+ sequence: int = int(timezone.now().timestamp())
87
90
  random_number: int = choice(range(1000, 9999)) # nosec B311
88
91
  sequence: str = f"{sequence}{random_number}"
89
92
  chk: int = int(sequence) % 11
@@ -197,7 +200,7 @@ class SimpleUniqueIdentifier:
197
200
  def model_cls(self) -> type[models.Model]:
198
201
  return django_apps.get_model(self.model)
199
202
 
200
- def update_identifier_model(self, **kwargs) -> bool:
203
+ def update_identifier_model(self, **kwargs) -> bool | IdentifierModel:
201
204
  """Attempts to update identifier_model and returns True (or instance)
202
205
  if successful else False if identifier already exists.
203
206
  """
@@ -212,5 +215,6 @@ class SimpleUniqueIdentifier:
212
215
  try:
213
216
  self.model_cls.objects.get(identifier=self.identifier)
214
217
  except ObjectDoesNotExist:
218
+ opts = {k: v for k, v in opts.items() if v is not None}
215
219
  return self.model_cls.objects.create(**opts)
216
220
  return False
@@ -1,5 +1,6 @@
1
+ from django.utils import timezone
2
+
1
3
  from edc_registration import get_registered_subject_model_cls
2
- from edc_utils import get_utcnow
3
4
 
4
5
  from .research_identifier import ResearchIdentifier
5
6
 
@@ -26,5 +27,5 @@ class SubjectIdentifier(ResearchIdentifier):
26
27
  site=self.site,
27
28
  subject_type=self.identifier_type,
28
29
  last_name=self.last_name,
29
- registration_datetime=get_utcnow(),
30
+ registration_datetime=timezone.now(),
30
31
  )
edc_lab/auths.py CHANGED
@@ -9,6 +9,7 @@ from edc_auth.constants import (
9
9
  PII_VIEW,
10
10
  )
11
11
  from edc_auth.site_auths import site_auths
12
+ from edc_export.constants import EXPORT
12
13
 
13
14
  from .auth_objects import (
14
15
  LAB,
@@ -18,26 +19,28 @@ from .auth_objects import (
18
19
  lab_view_codenames,
19
20
  )
20
21
 
21
- site_auths.add_group(*lab_codenames, name=LAB)
22
- site_auths.add_group(*lab_view_codenames, name=LAB_VIEW)
23
-
24
- if django_apps.is_installed("edc_export"):
25
- from edc_export.constants import EXPORT
26
-
27
- site_auths.update_group(
28
- "edc_lab.export_aliquot",
29
- "edc_lab.export_box",
30
- "edc_lab.export_boxitem",
31
- "edc_lab.export_boxtype",
32
- "edc_lab.export_order",
33
- "edc_lab.export_panel",
34
- "edc_lab.export_result",
35
- "edc_lab.export_resultitem",
36
- name=EXPORT,
37
- )
38
-
39
-
40
- site_auths.add_role(ADMINISTRATION, EVERYONE, LAB, PII_VIEW, name=LAB_TECHNICIAN_ROLE)
41
- site_auths.update_role(LAB, name=CLINICIAN_ROLE)
42
- site_auths.update_role(LAB, name=NURSE_ROLE)
43
- site_auths.update_role(LAB_VIEW, name=AUDITOR_ROLE)
22
+
23
+ def update_site_auths():
24
+ site_auths.add_group(*lab_codenames, name=LAB)
25
+ site_auths.add_group(*lab_view_codenames, name=LAB_VIEW)
26
+
27
+ if django_apps.is_installed("edc_export"):
28
+ site_auths.update_group(
29
+ "edc_lab.export_aliquot",
30
+ "edc_lab.export_box",
31
+ "edc_lab.export_boxitem",
32
+ "edc_lab.export_boxtype",
33
+ "edc_lab.export_order",
34
+ "edc_lab.export_panel",
35
+ "edc_lab.export_result",
36
+ "edc_lab.export_resultitem",
37
+ name=EXPORT,
38
+ )
39
+
40
+ site_auths.add_role(ADMINISTRATION, EVERYONE, LAB, PII_VIEW, name=LAB_TECHNICIAN_ROLE)
41
+ site_auths.update_role(LAB, name=CLINICIAN_ROLE)
42
+ site_auths.update_role(LAB, name=NURSE_ROLE)
43
+ site_auths.update_role(LAB_VIEW, name=AUDITOR_ROLE)
44
+
45
+
46
+ update_site_auths()
@@ -90,18 +90,15 @@ class AliquotCreator:
90
90
  parent_segment=self.parent_segment,
91
91
  )
92
92
 
93
- parent_identifier = parent_identifier or aliquot_identifier_obj.identifier
94
-
95
- aliquot = self.aliquot_model_cls.objects.create(
93
+ return self.aliquot_model_cls.objects.create(
96
94
  aliquot_identifier=aliquot_identifier_obj.identifier,
97
95
  aliquot_type=aliquot_type.name,
98
96
  alpha_code=aliquot_type.alpha_code,
99
97
  count=count,
100
98
  numeric_code=aliquot_type.numeric_code,
101
- parent_identifier=parent_identifier,
99
+ parent_identifier=parent_identifier or aliquot_identifier_obj.identifier,
102
100
  identifier_prefix=self.identifier_prefix,
103
- is_primary=True if self.is_primary else False,
104
- requisition_identifier=self.requisition_identifier,
105
- subject_identifier=self.subject_identifier,
101
+ is_primary=bool(self.is_primary),
102
+ requisition_identifier=self.requisition_identifier or "",
103
+ subject_identifier=self.subject_identifier or "",
106
104
  )
107
- return aliquot
@@ -1,3 +1,11 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from edc_lab import AliquotCreator, AliquotType
7
+
8
+
1
9
  class PrimaryAliquotError(Exception):
2
10
  pass
3
11
 
@@ -11,11 +19,12 @@ class PrimaryAliquot:
11
19
 
12
20
  def __init__(
13
21
  self,
14
- aliquot_type=None,
15
- subject_identifier=None,
16
- requisition_identifier=None,
17
- identifier_prefix=None,
18
- aliquot_creator_cls=None,
22
+ *,
23
+ aliquot_creator_cls: type[AliquotCreator],
24
+ aliquot_type: AliquotType | None = None,
25
+ subject_identifier: str | None = None,
26
+ requisition_identifier: str | None = None,
27
+ identifier_prefix: str | None = None,
19
28
  ):
20
29
  self._object = None
21
30
  self.aliquot_creator_cls = aliquot_creator_cls