clinicedc 2.0.1__py3-none-any.whl → 2.0.3__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 (855) hide show
  1. {clinicedc-2.0.1.dist-info → clinicedc-2.0.3.dist-info}/METADATA +15 -22
  2. {clinicedc-2.0.1.dist-info → clinicedc-2.0.3.dist-info}/RECORD +854 -787
  3. {clinicedc-2.0.1.dist-info → clinicedc-2.0.3.dist-info}/WHEEL +1 -1
  4. edc_action_item/action.py +10 -30
  5. edc_action_item/action_with_notification.py +1 -2
  6. edc_action_item/admin/action_item_admin.py +2 -6
  7. edc_action_item/admin_site.py +1 -3
  8. edc_action_item/auths.py +1 -3
  9. edc_action_item/create_or_update_action_type.py +1 -3
  10. edc_action_item/data_fixers.py +6 -20
  11. edc_action_item/forms/action_item_form.py +1 -3
  12. edc_action_item/management/commands/inspect_action_items.py +3 -9
  13. edc_action_item/migrations/0001_initial.py +4 -5
  14. edc_action_item/migrations/0003_auto_20180116_1528.py +2 -1
  15. edc_action_item/migrations/0006_auto_20180707_1659.py +3 -4
  16. edc_action_item/migrations/0007_auto_20180707_1715.py +1 -3
  17. edc_action_item/migrations/0008_auto_20180809_0303.py +2 -1
  18. edc_action_item/migrations/0014_auto_20181121_1738.py +2 -6
  19. edc_action_item/migrations/0015_auto_20190114_0250.py +4 -3
  20. edc_action_item/migrations/0021_auto_20190628_2113.py +1 -3
  21. edc_action_item/migrations/0022_auto_20190628_2136.py +2 -6
  22. edc_action_item/migrations/0030_edcpermissions.py +1 -1
  23. edc_action_item/migrations/0033_alter_actionitem_managers.py +1 -0
  24. edc_action_item/migrations/0034_alter_actionitem_device_created_and_more.py +13 -37
  25. edc_action_item/models/action_item.py +2 -6
  26. edc_action_item/models/action_model_mixin.py +5 -16
  27. edc_action_item/models/action_type.py +1 -3
  28. edc_action_item/models/reference.py +1 -2
  29. edc_action_item/models/signals.py +3 -9
  30. edc_action_item/site_action_items.py +5 -15
  31. edc_action_item/templatetags/action_item_extras.py +1 -3
  32. edc_action_item/view_utils/action_item_button.py +1 -3
  33. edc_action_item/view_utils/action_item_popover_list_item.py +1 -2
  34. edc_adherence/migrations/0002_nonadherencereasons_plural_name.py +1 -3
  35. edc_adherence/model_admin_mixin.py +1 -3
  36. edc_adverse_event/action_items/ae_followup_action.py +2 -6
  37. edc_adverse_event/action_items/ae_initial_action.py +3 -7
  38. edc_adverse_event/auth_objects.py +2 -6
  39. edc_adverse_event/constants.py +1 -3
  40. edc_adverse_event/form_validator_mixins/death_report_form_validator.py +1 -3
  41. edc_adverse_event/form_validator_mixins/requires_death_report_form_validator_mixin.py +2 -7
  42. edc_adverse_event/form_validators/hospitalization.py +1 -3
  43. edc_adverse_event/migrations/0003_auto_20191026_2231.py +3 -9
  44. edc_adverse_event/migrations/0008_auto_20220825_0451.py +1 -1
  45. edc_adverse_event/migrations/0009_auto_20220907_0157.py +1 -1
  46. edc_adverse_event/migrations/0010_auto_20220913_2139.py +4 -12
  47. edc_adverse_event/migrations/0013_alter_aeactionclassification_device_created_and_more.py +11 -31
  48. edc_adverse_event/model_mixins/ae_followup/ae_followup_fields_model_mixin.py +1 -3
  49. edc_adverse_event/model_mixins/ae_followup/ae_followup_model_mixin.py +1 -5
  50. edc_adverse_event/model_mixins/ae_initial/ae_initial_ae_model_mixin.py +1 -3
  51. edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +1 -3
  52. edc_adverse_event/model_mixins/ae_initial/ae_initial_susar_model_mixin.py +1 -2
  53. edc_adverse_event/model_mixins/ae_special_interest/aesi_model_mixin.py +1 -5
  54. edc_adverse_event/model_mixins/ae_susar/ae_susar_model_mixin.py +1 -5
  55. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +2 -6
  56. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_model_mixin.py +1 -5
  57. edc_adverse_event/model_mixins/death_report/death_report_extra_fields_model_mixin.py +1 -2
  58. edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +2 -5
  59. edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +2 -7
  60. edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +1 -3
  61. edc_adverse_event/modeladmin_mixins/ae_tmg_admin_mixin.py +1 -3
  62. edc_adverse_event/modeladmin_mixins/death_report_admin_mixin.py +6 -10
  63. edc_adverse_event/modelform_mixins/ae_tmg_modelform_mixin.py +1 -3
  64. edc_adverse_event/models/signals.py +3 -9
  65. edc_adverse_event/pdf_reports/ae_pdf_report.py +6 -18
  66. edc_adverse_event/pdf_reports/death_pdf_report.py +3 -9
  67. edc_adverse_event/templatetags/edc_adverse_event_extras.py +5 -15
  68. edc_adverse_event/utils.py +2 -6
  69. edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +1 -3
  70. edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +1 -3
  71. edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +2 -6
  72. edc_adverse_event/view_utils/tmg_button.py +2 -6
  73. edc_adverse_event/views/home_view.py +1 -3
  74. edc_adverse_event/views/tmg/death_listboard_view.py +1 -3
  75. edc_adverse_event/views/tmg/home_view.py +2 -6
  76. edc_adverse_event/views/tmg/summary_listboard_view.py +1 -3
  77. edc_appointment/admin/appointment_admin.py +1 -3
  78. edc_appointment/admin/list_filters.py +1 -3
  79. edc_appointment/admin_site.py +1 -3
  80. edc_appointment/analytics/dataframes/get_appointment_df.py +2 -6
  81. edc_appointment/appointment_reason_updater.py +2 -5
  82. edc_appointment/appointment_status_updater.py +1 -4
  83. edc_appointment/constants.py +1 -3
  84. edc_appointment/creators/appointment_creator.py +4 -10
  85. edc_appointment/creators/unscheduled_appointment_creator.py +3 -7
  86. edc_appointment/creators/utils.py +4 -0
  87. edc_appointment/form_validator_mixins/next_appointment_crf_form_validator_mixin.py +3 -10
  88. edc_appointment/form_validator_mixins/window_period_form_validator_mixin.py +3 -9
  89. edc_appointment/form_validators/appointment_form_validator.py +11 -37
  90. edc_appointment/form_validators/next_appointment_crf_form_validator.py +1 -3
  91. edc_appointment/form_validators/utils.py +1 -3
  92. edc_appointment/managers.py +2 -6
  93. edc_appointment/migrations/0002_auto_20161126_1156.py +5 -8
  94. edc_appointment/migrations/0003_auto_20161127_2226.py +7 -16
  95. edc_appointment/migrations/0006_auto_20170106_2118.py +2 -1
  96. edc_appointment/migrations/0008_auto_20171115_1601.py +3 -4
  97. edc_appointment/migrations/0014_auto_20180116_1411.py +2 -1
  98. edc_appointment/migrations/0024_auto_20200911_0425.py +1 -1
  99. edc_appointment/migrations/0034_appointmenttype_alter_appointment_appt_type_and_more.py +2 -4
  100. edc_appointment/migrations/0036_auto_20230124_1822.py +2 -6
  101. edc_appointment/migrations/0040_appointment_appt_type_other_and_more.py +1 -0
  102. edc_appointment/migrations/0042_alter_appointment_device_created_and_more.py +5 -13
  103. edc_appointment/migrations/0046_infosources.py +1 -3
  104. edc_appointment/migrations/0047_alter_appointment_options_and_more.py +1 -3
  105. edc_appointment/model_mixins/appointment_methods_model_mixin.py +1 -5
  106. edc_appointment/model_mixins/appointment_model_mixin.py +2 -8
  107. edc_appointment/model_mixins/next_appointment_crf_model_mixin.py +1 -3
  108. edc_appointment/modeladmin_mixins/next_appointment_crf_modeladmin_mixin.py +1 -3
  109. edc_appointment/modelform_mixins/next_appointment_crf_modelform_mixins.py +1 -5
  110. edc_appointment/models/signals.py +5 -17
  111. edc_appointment/utils.py +11 -33
  112. edc_appointment/view_mixins/appointment_view_mixin.py +2 -6
  113. edc_auth/admin/list_filters.py +2 -6
  114. edc_auth/admin/role_admin.py +1 -3
  115. edc_auth/admin/user_admin.py +4 -12
  116. edc_auth/admin/user_profile_admin.py +2 -5
  117. edc_auth/auth_updater/auth_updater.py +1 -3
  118. edc_auth/auth_updater/group_updater.py +3 -9
  119. edc_auth/forms.py +1 -3
  120. edc_auth/get_app_codenames.py +1 -3
  121. edc_auth/import_users.py +3 -9
  122. edc_auth/management/commands/export_users.py +1 -3
  123. edc_auth/management/commands/reset_password.py +1 -3
  124. edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +4 -12
  125. edc_auth/migrations/0015_auto_20191026_2149.py +1 -3
  126. edc_auth/migrations/0016_auto_20191026_2153.py +1 -3
  127. edc_auth/migrations/0025_permissions.py +1 -1
  128. edc_auth/migrations/0029_alter_edcpermissions_device_created_and_more.py +5 -13
  129. edc_auth/models/__init__.py +1 -3
  130. edc_auth/models/signals.py +2 -6
  131. edc_auth/models/user_profile.py +1 -3
  132. edc_auth/password_setter.py +1 -3
  133. edc_auth/system_checks.py +1 -5
  134. edc_auth/urls_for_accounts.py +1 -3
  135. edc_auth/utils.py +3 -9
  136. edc_consent/actions.py +3 -9
  137. edc_consent/consent_definition.py +2 -6
  138. edc_consent/consent_definition_extension.py +4 -12
  139. edc_consent/field_mixins/citizen_fields_mixin.py +2 -4
  140. edc_consent/field_mixins/identity_fields_mixin.py +1 -2
  141. edc_consent/field_mixins/personal_fields_mixin.py +8 -3
  142. edc_consent/field_mixins/site_fields_mixin.py +1 -2
  143. edc_consent/form_validators/subject_consent_form_validator.py +2 -7
  144. edc_consent/migrations/0001_initial.py +1 -1
  145. edc_consent/migrations/0002_alter_edcpermissions_device_created_and_more.py +3 -7
  146. edc_consent/model_mixins/consent_extension_model_mixin.py +1 -3
  147. edc_consent/model_mixins/consent_model_mixin.py +3 -9
  148. edc_consent/modeladmin_mixins/consent_model_admin_mixin.py +7 -17
  149. edc_consent/modelform_mixins/consent_modelform_mixin/consent_modelform_validation_mixin.py +3 -8
  150. edc_consent/modelform_mixins/requires_consent_modelform_mixin.py +1 -3
  151. edc_consent/models/signals.py +2 -6
  152. edc_consent/site_consents.py +5 -17
  153. edc_consent/system_checks.py +3 -9
  154. edc_consent/validators.py +1 -2
  155. edc_consent/view_mixins/consent_view_mixins.py +3 -5
  156. edc_crf/crf_form_validator.py +2 -6
  157. edc_crf/crf_form_validator_mixins.py +2 -6
  158. edc_crf/migrations/0004_alter_crfstatus_device_created_and_more.py +3 -7
  159. edc_crf/utils.py +1 -3
  160. edc_dashboard/management/commands/update_search_slugs.py +1 -3
  161. edc_dashboard/migrations/0001_initial.py +1 -1
  162. edc_dashboard/migrations/0003_alter_edcpermissions_device_created_and_more.py +3 -7
  163. edc_dashboard/templatetags/edc_dashboard_extras.py +2 -6
  164. edc_dashboard/view_mixins/administration_view_mixin.py +1 -3
  165. edc_dashboard/view_mixins/edc_view_mixin.py +1 -3
  166. edc_dashboard/views/administration_view.py +1 -3
  167. edc_data_manager/action_items.py +1 -3
  168. edc_data_manager/admin/actions.py +3 -9
  169. edc_data_manager/admin/data_query_admin.py +4 -12
  170. edc_data_manager/admin/query_rule_admin.py +4 -13
  171. edc_data_manager/auths.py +1 -3
  172. edc_data_manager/forms/data_query.py +2 -6
  173. edc_data_manager/forms/query_rule.py +1 -3
  174. edc_data_manager/get_longitudinal_value.py +2 -5
  175. edc_data_manager/handlers/handlers.py +2 -6
  176. edc_data_manager/migrations/0001_initial.py +4 -3
  177. edc_data_manager/migrations/0003_auto_20190806_1749.py +2 -6
  178. edc_data_manager/migrations/0004_auto_20190806_1750.py +1 -3
  179. edc_data_manager/migrations/0025_edcpermissions.py +1 -1
  180. edc_data_manager/migrations/0027_alter_dataquery_dm_user.py +1 -1
  181. edc_data_manager/migrations/0028_alter_dataquery_options_alter_queryrule_options_and_more.py +2 -1
  182. edc_data_manager/migrations/0029_alter_dataquery_managers.py +2 -1
  183. edc_data_manager/migrations/0030_alter_datadictionary_device_created_and_more.py +15 -43
  184. edc_data_manager/models/model_mixins.py +1 -3
  185. edc_data_manager/populate_data_dictionary.py +1 -2
  186. edc_data_manager/post_migrate_signals.py +1 -3
  187. edc_data_manager/site_data_manager.py +1 -3
  188. edc_document_status/model_mixins.py +1 -3
  189. edc_egfr/__init__.py +1 -0
  190. edc_egfr/admin/__init__.py +1 -0
  191. edc_egfr/admin/egfr_drop_notification_admin_mixin.py +73 -0
  192. edc_egfr/apps.py +5 -0
  193. edc_egfr/calculators/__init__.py +4 -0
  194. edc_egfr/calculators/base_egrfr.py +56 -0
  195. edc_egfr/calculators/egfr_ckd_epi.py +68 -0
  196. edc_egfr/calculators/egfr_cockcroft_gault.py +63 -0
  197. edc_egfr/calculators/percent_change.py +7 -0
  198. edc_egfr/constants.py +1 -0
  199. edc_egfr/egfr.py +237 -0
  200. edc_egfr/form_validator_mixins/__init__.py +4 -0
  201. edc_egfr/form_validator_mixins/egfr_form_validator_mixins.py +55 -0
  202. edc_egfr/get_drop_notification_model.py +10 -0
  203. edc_egfr/get_egfr_for_subject.py +31 -0
  204. edc_egfr/model_mixins/__init__.py +2 -0
  205. edc_egfr/model_mixins/egfr_drop_notification_model_mixin.py +63 -0
  206. edc_egfr/model_mixins/egfr_model_mixin.py +120 -0
  207. edc_export/archive_exporter.py +2 -6
  208. edc_export/exportables.py +2 -6
  209. edc_export/files_emailer.py +1 -3
  210. edc_export/management/commands/import_receipts.py +1 -3
  211. edc_export/managers.py +3 -9
  212. edc_export/migrations/0001_initial.py +15 -36
  213. edc_export/migrations/0005_exportdata_importdata.py +1 -3
  214. edc_export/migrations/0006_auto_20200512_0208.py +2 -6
  215. edc_export/migrations/0010_auto_20210910_1636.py +2 -6
  216. edc_export/migrations/0013_edcpermissions.py +1 -1
  217. edc_export/migrations/0015_alter_datarequest_managers_and_more.py +2 -1
  218. edc_export/migrations/0016_alter_datarequest_device_created_and_more.py +27 -79
  219. edc_export/migrations/0017_alter_datarequest_options_and_more.py +2 -6
  220. edc_export/migrations/0020_remove_datarequesthistory_edc_export__exporte_ba8050_idx_and_more.py +2 -6
  221. edc_export/model_exporter/model_exporter.py +4 -15
  222. edc_export/model_exporter/object_history_helpers.py +1 -3
  223. edc_export/model_exporter/value_getter.py +5 -14
  224. edc_export/models/signals.py +1 -3
  225. edc_export/models/upload_export_receipt_file.py +1 -3
  226. edc_export/utils.py +1 -4
  227. edc_export/views/export_selected_models_view.py +6 -17
  228. edc_facility/default_definitions.py +1 -3
  229. edc_facility/facility.py +4 -14
  230. edc_facility/import_holidays.py +1 -3
  231. edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +4 -6
  232. edc_facility/migrations/0006_alter_healthfacility_health_facility_type.py +1 -1
  233. edc_facility/migrations/0008_alter_healthfacility_device_created_and_more.py +5 -13
  234. edc_facility/models/holiday.py +1 -3
  235. edc_facility/utils.py +1 -3
  236. edc_fieldsets/fieldsets_modeladmin_mixin.py +1 -3
  237. edc_form_describer/form_describer.py +3 -9
  238. edc_form_describer/make_forms_reference.py +1 -3
  239. edc_form_describer/management/commands/make_forms_reference.py +1 -3
  240. edc_form_runners/admin/issue_admin.py +2 -6
  241. edc_form_runners/form_runner.py +4 -13
  242. edc_form_runners/form_runner_by_scr_id.py +1 -3
  243. edc_form_runners/get_form_runner.py +1 -3
  244. edc_form_runners/get_form_runner_by_src_id.py +3 -3
  245. edc_form_runners/management/commands/run_form_runners.py +1 -3
  246. edc_form_runners/migrations/0001_initial.py +2 -4
  247. edc_form_runners/run_form_runners.py +1 -3
  248. edc_form_runners/utils.py +1 -3
  249. edc_form_validators/applicable_field_validator.py +6 -17
  250. edc_form_validators/base_form_validator.py +1 -3
  251. edc_form_validators/date_range_validator.py +4 -12
  252. edc_form_validators/date_validator.py +3 -9
  253. edc_form_validators/many_to_many_field_validator.py +1 -3
  254. edc_form_validators/other_specify_field_validator.py +3 -7
  255. edc_form_validators/range_field_validator.py +1 -3
  256. edc_form_validators/required_field_validator.py +5 -18
  257. edc_glucose/__init__.py +0 -0
  258. edc_glucose/apps.py +6 -0
  259. edc_glucose/constants.py +3 -0
  260. edc_glucose/fieldsets.py +14 -0
  261. edc_glucose/form_validators/__init__.py +6 -0
  262. edc_glucose/form_validators/fasting_form_validator.py +12 -0
  263. edc_glucose/form_validators/fbg_form_validator_mixin.py +32 -0
  264. edc_glucose/form_validators/fbg_ogtt_form_validator_mixin.py +47 -0
  265. edc_glucose/form_validators/glucose_form_validator.py +44 -0
  266. edc_glucose/form_validators/glucose_form_validator_mixin.py +53 -0
  267. edc_glucose/form_validators/ogtt_form_validator_mixin.py +91 -0
  268. edc_glucose/list_filters.py +42 -0
  269. edc_glucose/migrations/__init__.py +0 -0
  270. edc_glucose/model_mixin_factories/__init__.py +4 -0
  271. edc_glucose/model_mixin_factories/fasting_model_mixin_factory.py +63 -0
  272. edc_glucose/model_mixin_factories/fbg_model_mixin_factory.py +48 -0
  273. edc_glucose/model_mixin_factories/glucose_model_mixin_factory.py +49 -0
  274. edc_glucose/model_mixin_factories/ogtt_model_mixin_factory.py +71 -0
  275. edc_glucose/model_mixins/__init__.py +5 -0
  276. edc_glucose/model_mixins/fasting_model_mixin.py +15 -0
  277. edc_glucose/model_mixins/fbg_model_mixin.py +10 -0
  278. edc_glucose/model_mixins/glucose_model_mixin.py +17 -0
  279. edc_glucose/model_mixins/hba1c_model_mixin.py +42 -0
  280. edc_glucose/model_mixins/ogtt_model_mixin.py +10 -0
  281. edc_glucose/models.py +0 -0
  282. edc_glucose/utils.py +42 -0
  283. edc_identifier/admin_site.py +1 -3
  284. edc_identifier/identifier.py +1 -3
  285. edc_identifier/migrations/0001_initial.py +3 -4
  286. edc_identifier/migrations/0001_squashed_0018_auto_20180128_1054.py +3 -2
  287. edc_identifier/migrations/0005_alter_identifiermodel_managers.py +2 -1
  288. edc_identifier/migrations/0005_historicalidentifierhistory_historicalidentifiertracker_historicalsubjectidentifier.py +4 -5
  289. edc_identifier/migrations/0006_auto_20161127_2226.py +16 -43
  290. edc_identifier/migrations/0007_alter_identifiermodel_device_created_and_more.py +3 -7
  291. edc_identifier/migrations/0007_auto_20161204_2227.py +4 -7
  292. edc_identifier/migrations/0009_auto_20161221_2323.py +1 -0
  293. edc_identifier/migrations/0010_auto_20170112_0602.py +2 -1
  294. edc_identifier/migrations/0012_auto_20171116_1606.py +2 -1
  295. edc_identifier/migrations/0013_auto_20171230_1316.py +3 -9
  296. edc_identifier/research_identifier.py +3 -11
  297. edc_identifier/short_identifier.py +5 -9
  298. edc_identifier/utils.py +1 -3
  299. edc_lab/admin/modeladmin_mixins.py +2 -8
  300. edc_lab/aliquot_types.py +1 -3
  301. edc_lab/form_validators/requisition_form_validator_mixin.py +1 -3
  302. edc_lab/forms/box_type_form.py +4 -6
  303. edc_lab/lab/aliquot_type.py +2 -6
  304. edc_lab/lab/manifest.py +2 -6
  305. edc_lab/lab/primary_aliquot.py +1 -3
  306. edc_lab/lab/requisition_panel.py +1 -3
  307. edc_lab/lab/requisition_panel_group.py +2 -6
  308. edc_lab/lab/specimen.py +1 -3
  309. edc_lab/labels/aliquot_label.py +4 -6
  310. edc_lab/labels/manifest_label.py +1 -3
  311. edc_lab/migrations/0001_initial.py +12 -29
  312. edc_lab/migrations/0002_auto_20170305_1939.py +4 -12
  313. edc_lab/migrations/0007_auto_20170321_1119.py +2 -6
  314. edc_lab/migrations/0008_auto_20170921_0719.py +2 -1
  315. edc_lab/migrations/0010_auto_20171127_1541.py +3 -2
  316. edc_lab/migrations/0012_auto_20180114_1438.py +2 -1
  317. edc_lab/migrations/0013_auto_20180117_1438.py +2 -1
  318. edc_lab/migrations/0022_auto_20211210_1839.py +1 -0
  319. edc_lab/migrations/0024_alter_manifestitem_managers.py +2 -1
  320. edc_lab/migrations/0027_alter_aliquot_managers_alter_box_managers_and_more.py +1 -1
  321. edc_lab/migrations/0028_alter_aliquot_device_created_and_more.py +43 -127
  322. edc_lab/model_mixins/aliquot/aliquot_label_mixin.py +1 -3
  323. edc_lab/model_mixins/aliquot/aliquot_model_mixin.py +4 -12
  324. edc_lab/model_mixins/requisition/requisition_identifier_mixin.py +1 -3
  325. edc_lab/model_mixins/shipping/manifest_model_mixin.py +1 -3
  326. edc_lab/models/box_item.py +1 -3
  327. edc_lab/models/box_type.py +1 -3
  328. edc_lab/models/manifest/manifest.py +3 -9
  329. edc_lab/models/manifest/manifest_item.py +1 -3
  330. edc_lab/models/order.py +1 -3
  331. edc_lab/models/signals.py +1 -3
  332. edc_lab/patterns.py +1 -3
  333. edc_lab/pdf_reports/manifest_pdf_report.py +9 -27
  334. edc_lab/post_migrate_signals.py +1 -3
  335. edc_lab/site_labs.py +4 -10
  336. edc_lab_dashboard/migrations/0001_initial.py +1 -1
  337. edc_lab_dashboard/migrations/0002_alter_edcpermissions_device_created_and_more.py +3 -7
  338. edc_lab_dashboard/view_mixins/box_view_mixin.py +1 -3
  339. edc_lab_dashboard/view_mixins/manifest_view_mixin.py +4 -12
  340. edc_lab_dashboard/views/action_views/receive_view.py +1 -3
  341. edc_lab_dashboard/views/action_views/verify_box_item_view.py +1 -3
  342. edc_lab_dashboard/views/listboard_filters/aliquot_listboard_view_filters.py +2 -6
  343. edc_lab_dashboard/views/listboard_filters/manifest_listboard_filters.py +1 -3
  344. edc_lab_dashboard/views/listboard_views/base_box_item_listboard_view.py +1 -3
  345. edc_lab_dashboard/views/listboard_views/manifest_listboard_view.py +1 -3
  346. edc_lab_dashboard/views/listboard_views/process_listboard_view.py +2 -6
  347. edc_lab_dashboard/views/listboard_views/receive_listboard_view.py +2 -6
  348. edc_lab_dashboard/views/listboard_views/requisition_listboard_view.py +2 -6
  349. edc_lab_results/action_items.py +1 -3
  350. edc_lab_results/form_validator_mixins/blood_results_fbg_form_validator_mixin.py +2 -4
  351. edc_lab_results/form_validator_mixins/blood_results_form_validator_mixin.py +1 -3
  352. edc_lab_results/get_summary.py +3 -5
  353. edc_lab_results/model_mixin_factories/__init__.py +10 -0
  354. edc_lab_results/{model_mixin_factory → model_mixin_factories}/field_attrs.py +8 -8
  355. edc_lab_results/{model_mixin_factory → model_mixin_factories}/reportable_result_model_mixin_factory.py +2 -0
  356. edc_lab_results/{model_mixin_factory → model_mixin_factories}/result_model_mixin_factory.py +2 -0
  357. edc_lab_results/model_mixins/blood_result_model_mixin.py +2 -5
  358. edc_lab_results/model_mixins/electrolytes_model_mixins.py +1 -1
  359. edc_lab_results/model_mixins/fbc_model_mixins.py +1 -1
  360. edc_lab_results/model_mixins/fbg_model_mixin.py +6 -3
  361. edc_lab_results/model_mixins/glucose_model_mixin.py +2 -2
  362. edc_lab_results/model_mixins/hba1c_model_mixin.py +2 -28
  363. edc_lab_results/model_mixins/insulin_model_mixin.py +4 -11
  364. edc_lab_results/model_mixins/lft_model_mixins.py +1 -1
  365. edc_lab_results/model_mixins/lipid_model_mixins.py +1 -1
  366. edc_lab_results/model_mixins/proteinuria_model_mixin.py +1 -1
  367. edc_lab_results/model_mixins/rft_model_mixins.py +1 -1
  368. edc_label/apps.py +1 -2
  369. edc_label/migrations/0001_initial.py +1 -1
  370. edc_label/migrations/0003_alter_zpllabeltemplates_device_created_and_more.py +3 -7
  371. edc_label/printer.py +2 -6
  372. edc_label/printers_mixin.py +1 -3
  373. edc_label/urls.py +1 -3
  374. edc_label/view_mixins.py +1 -3
  375. edc_label/views/print_label_view.py +1 -3
  376. edc_list_data/model_mixins.py +1 -3
  377. edc_list_data/preload_data.py +2 -6
  378. edc_list_data/site_list_data.py +1 -3
  379. edc_listboard/migrations/0001_initial.py +1 -1
  380. edc_listboard/migrations/0003_alter_listboard_device_created_and_more.py +3 -7
  381. edc_listboard/view_mixins/listboard_filter_view_mixin.py +5 -15
  382. edc_listboard/view_mixins/search_listboard_view_mixin.py +2 -6
  383. edc_listboard/views/listboard_view.py +2 -6
  384. edc_listboard/views/screen/screening_listboard_view.py +1 -3
  385. edc_listboard/views/subject/subject_listboard_view.py +1 -3
  386. edc_locator/forms/subject_locator_form_validator.py +4 -12
  387. edc_locator/migrations/0001_initial.py +3 -2
  388. edc_locator/migrations/0003_auto_20180103_1351.py +2 -1
  389. edc_locator/migrations/0004_auto_20180106_2148.py +2 -1
  390. edc_locator/migrations/0007_auto_20180117_1819.py +2 -1
  391. edc_locator/migrations/0011_auto_20181007_0053.py +1 -1
  392. edc_locator/migrations/0013_auto_20181007_0054.py +2 -3
  393. edc_locator/migrations/0014_auto_20181009_0545.py +1 -0
  394. edc_locator/migrations/0032_alter_subjectlocator_managers.py +1 -1
  395. edc_locator/migrations/0034_alter_historicalsubjectlocator_device_created_and_more.py +5 -13
  396. edc_locator/modeladmin_mixins.py +1 -3
  397. edc_locator/view_mixins/subject_locator_view_mixins.py +1 -3
  398. edc_ltfu/admin.py +1 -3
  399. edc_ltfu/forms/ltfu_form.py +1 -3
  400. edc_ltfu/forms/ltfu_form_validator_mixin.py +1 -2
  401. edc_ltfu/modelform_mixins.py +3 -8
  402. edc_metadata/admin/modeladmin_mixins.py +2 -8
  403. edc_metadata/management/commands/validate_entry_status.py +1 -3
  404. edc_metadata/metadata/metadata.py +12 -41
  405. edc_metadata/metadata/metadata_getter.py +2 -9
  406. edc_metadata/metadata/requisition_metadata_getter.py +1 -3
  407. edc_metadata/metadata_handler.py +3 -9
  408. edc_metadata/metadata_helper/metadata_helper_mixin.py +1 -3
  409. edc_metadata/metadata_mixins/source_model_metadata_mixin.py +3 -9
  410. edc_metadata/metadata_refresher.py +3 -9
  411. edc_metadata/metadata_rules/crf/crf_rule_group.py +2 -5
  412. edc_metadata/metadata_rules/persistant_singleton_mixin.py +3 -3
  413. edc_metadata/metadata_rules/requisition/requisition_rule_group.py +1 -2
  414. edc_metadata/metadata_rules/rule_evaluator.py +1 -3
  415. edc_metadata/metadata_rules/rule_group.py +2 -6
  416. edc_metadata/metadata_rules/rule_group_meta_options.py +1 -3
  417. edc_metadata/metadata_updater.py +1 -3
  418. edc_metadata/metadata_wrappers/metadata_wrapper.py +1 -3
  419. edc_metadata/migrations/0001_initial.py +2 -1
  420. edc_metadata/migrations/0002_auto_20161127_2226.py +6 -13
  421. edc_metadata/migrations/0005_auto_20170112_0602.py +2 -1
  422. edc_metadata/migrations/0007_auto_20170810_1032.py +2 -1
  423. edc_metadata/migrations/0009_auto_20180116_1528.py +2 -1
  424. edc_metadata/migrations/0014_auto_20190707_0002.py +1 -1
  425. edc_metadata/migrations/0015_auto_20190709_0009.py +3 -5
  426. edc_metadata/migrations/0021_alter_crfmetadata_managers_and_more.py +1 -1
  427. edc_metadata/migrations/0023_alter_crfmetadata_device_created_and_more.py +5 -13
  428. edc_metadata/model_mixins/creates/creates_metadata_model_mixin.py +1 -3
  429. edc_metadata/model_mixins/updates/updates_metadata_model_mixin.py +1 -3
  430. edc_metadata/models/crf_metadata_model_mixin.py +2 -6
  431. edc_metadata/next_form_getter.py +1 -3
  432. edc_metadata/requisition/requisition_metadata_handler.py +3 -2
  433. edc_metadata/requisition/requisition_metadata_updater.py +1 -3
  434. edc_metadata/update_metadata_on_schedule_change.py +7 -14
  435. edc_model/models/fields/initials_field.py +1 -3
  436. edc_model/models/signals.py +1 -3
  437. edc_model/system_checks.py +1 -3
  438. edc_model/validators/duration.py +1 -3
  439. edc_model_admin/admin_site.py +1 -3
  440. edc_model_admin/changelist_buttons/model_admin_changelist_button_mixin.py +4 -12
  441. edc_model_admin/changelist_buttons/model_admin_changelist_model_button_mixin.py +1 -3
  442. edc_model_admin/dashboard/model_admin_crf_dashboard_mixin.py +1 -3
  443. edc_model_admin/dashboard/model_admin_dashboard_mixin.py +1 -3
  444. edc_model_admin/mixins/base_model_admin_redirect_mixin.py +2 -6
  445. edc_model_admin/mixins/inlines/limited_admin_inline_mixin.py +1 -3
  446. edc_model_admin/mixins/model_admin_bypass_default_form_cls_mixin.py +4 -12
  447. edc_model_admin/mixins/model_admin_form_auto_number_mixin.py +2 -6
  448. edc_model_admin/mixins/model_admin_form_instructions_mixin.py +2 -6
  449. edc_model_admin/mixins/model_admin_next_url_redirect_mixin.py +3 -9
  450. edc_model_admin/mixins/model_admin_protect_pii_mixin.py +1 -3
  451. edc_model_admin/mixins/model_admin_redirect_all_to_changelist_mixin.py +2 -6
  452. edc_model_admin/mixins/model_admin_redirect_on_delete_mixin.py +1 -3
  453. edc_model_admin/templatetags/edc_admin_modify.py +3 -9
  454. edc_model_fields/fields/initials_field.py +1 -3
  455. edc_model_form/mixins/inline_model_form_mixin.py +5 -9
  456. edc_model_to_dataframe/model_to_dataframe.py +15 -46
  457. edc_navbar/get_default_navbar.py +1 -3
  458. edc_navbar/migrations/0004_auto_20220825_0451.py +1 -1
  459. edc_navbar/migrations/0006_alter_edcpermissions_device_created_and_more.py +3 -7
  460. edc_navbar/navbar.py +1 -3
  461. edc_navbar/navbar_item.py +1 -3
  462. edc_navbar/site_navbars.py +2 -6
  463. edc_navbar/templatetags/edc_navbar_extras.py +1 -3
  464. edc_notification/admin_site.py +1 -3
  465. edc_notification/mailing_list_manager.py +5 -15
  466. edc_notification/migrations/0001_initial.py +2 -1
  467. edc_notification/migrations/0008_alter_notification_device_created_and_more.py +3 -7
  468. edc_notification/modeladmin_mixins.py +1 -3
  469. edc_notification/models/notification.py +1 -3
  470. edc_notification/models/signals.py +3 -10
  471. edc_notification/notification/model_notification.py +3 -9
  472. edc_notification/notification/notification.py +4 -12
  473. edc_notification/site_notifications.py +5 -14
  474. edc_offstudy/migrations/0001_initial.py +2 -1
  475. edc_offstudy/migrations/0002_auto_20180921_0434.py +4 -3
  476. edc_offstudy/migrations/0008_auto_20191102_0033.py +2 -1
  477. edc_offstudy/migrations/0015_auto_20220925_0032.py +1 -1
  478. edc_offstudy/migrations/0016_auto_20220929_1742.py +1 -0
  479. edc_offstudy/migrations/0018_alter_subjectoffstudy_managers.py +2 -1
  480. edc_offstudy/migrations/0019_alter_historicalsubjectoffstudy_device_created_and_more.py +5 -13
  481. edc_offstudy/model_mixins/offstudy_model_mixin.py +3 -3
  482. edc_offstudy/modelform_mixins/crf/offstudy_crf_modelform_mixin.py +2 -6
  483. edc_offstudy/templatetags/edc_offstudy_extras.py +2 -6
  484. edc_offstudy/utils.py +1 -3
  485. edc_pdf_reports/admin/modeladmin_mixins.py +1 -3
  486. edc_pdf_reports/crf_pdf_report.py +3 -9
  487. edc_pdf_reports/flowables/textbox.py +1 -3
  488. edc_pdf_reports/report.py +6 -18
  489. edc_pdf_reports/utils.py +1 -3
  490. edc_pdf_reports/views/pdf_intermediate_view.py +1 -3
  491. edc_pdf_reports/views/print_pdf_report_view.py +2 -6
  492. edc_pdutils/actions.py +4 -12
  493. edc_pdutils/choices.py +1 -4
  494. edc_pdutils/database.py +1 -3
  495. edc_pdutils/df_exporters/csv_crf_inline_tables_exporter.py +4 -12
  496. edc_pdutils/df_exporters/csv_exporter.py +7 -22
  497. edc_pdutils/df_handlers/crf_df_handler.py +3 -9
  498. edc_pdutils/df_handlers/df_handler.py +1 -3
  499. edc_pdutils/df_handlers/registered_subject_df_handler.py +1 -3
  500. edc_pdutils/management/commands/export_models.py +2 -6
  501. edc_pdutils/migrations/0001_initial.py +6 -9
  502. edc_pdutils/site.py +2 -6
  503. edc_pdutils/site_values_mappings.py +3 -9
  504. edc_pdutils/tables/aliquot.py +2 -9
  505. edc_pdutils/tables/consent.py +2 -6
  506. edc_pdutils/tables/crf.py +4 -12
  507. edc_pdutils/tables/requisition.py +4 -12
  508. edc_pdutils/tables/visit.py +1 -3
  509. edc_pdutils/utils/convert_dates_from_model.py +3 -9
  510. edc_pdutils/utils/convert_numerics_from_model.py +1 -3
  511. edc_pdutils/utils/convert_timedelta_from_model.py +1 -3
  512. edc_pdutils/utils/missing_subject_identifiers.py +1 -3
  513. edc_pharmacy/admin/actions/confirm_stock.py +2 -6
  514. edc_pharmacy/admin/actions/delete_order_items.py +1 -3
  515. edc_pharmacy/admin/actions/delete_receive_items.py +1 -3
  516. edc_pharmacy/admin/actions/print_stock_report.py +1 -3
  517. edc_pharmacy/admin/list_filters.py +5 -17
  518. edc_pharmacy/admin/model_admin_mixin.py +1 -3
  519. edc_pharmacy/admin/prescription/rx_admin.py +2 -6
  520. edc_pharmacy/admin/prescription/rx_refill_admin.py +1 -3
  521. edc_pharmacy/admin/reports/stock_availability_admin.py +1 -5
  522. edc_pharmacy/admin/stock/allocation_admin.py +5 -15
  523. edc_pharmacy/admin/stock/allocation_proxy_admin.py +1 -3
  524. edc_pharmacy/admin/stock/confirmation_admin.py +1 -3
  525. edc_pharmacy/admin/stock/confirmation_at_site_admin.py +4 -12
  526. edc_pharmacy/admin/stock/confirmation_at_site_item_admin.py +5 -17
  527. edc_pharmacy/admin/stock/dispense_admin.py +3 -11
  528. edc_pharmacy/admin/stock/dispense_item_admin.py +4 -14
  529. edc_pharmacy/admin/stock/order_admin.py +1 -3
  530. edc_pharmacy/admin/stock/order_item_admin.py +5 -15
  531. edc_pharmacy/admin/stock/receive_admin.py +4 -12
  532. edc_pharmacy/admin/stock/receive_item_admin.py +4 -12
  533. edc_pharmacy/admin/stock/repack_request_admin.py +2 -6
  534. edc_pharmacy/admin/stock/stock_adjustment_admin.py +1 -3
  535. edc_pharmacy/admin/stock/stock_admin.py +8 -24
  536. edc_pharmacy/admin/stock/stock_proxy_admin.py +1 -5
  537. edc_pharmacy/admin/stock/stock_request_item_admin.py +5 -15
  538. edc_pharmacy/admin/stock/stock_transfer_admin.py +4 -12
  539. edc_pharmacy/admin/stock/stock_transfer_item_admin.py +6 -18
  540. edc_pharmacy/admin/stock/storage_bin_admin.py +3 -11
  541. edc_pharmacy/admin/stock/storage_bin_item_admin.py +4 -14
  542. edc_pharmacy/analytics/dataframes/get_next_scheduled_visit_for_subjects_df.py +3 -9
  543. edc_pharmacy/analytics/dataframes/in_stock_for_subjects_df.py +2 -6
  544. edc_pharmacy/analytics/dataframes/stock_for_subjects.py +1 -3
  545. edc_pharmacy/form_validators/crf/study_medication_form_validator.py +9 -27
  546. edc_pharmacy/forms/stock/container_form.py +2 -6
  547. edc_pharmacy/forms/stock/receive_item_form.py +2 -6
  548. edc_pharmacy/forms/stock/repack_request_form.py +4 -11
  549. edc_pharmacy/forms/stock/stock_request_form.py +5 -14
  550. edc_pharmacy/forms/stock/stock_request_item_form.py +1 -3
  551. edc_pharmacy/labels/draw_bulk_stock_label_code128.py +1 -3
  552. edc_pharmacy/labels/draw_bulk_stock_label_code39.py +3 -9
  553. edc_pharmacy/labels/draw_patient_stock_label_code128.py +1 -3
  554. edc_pharmacy/migrations/0001_initial.py +7 -15
  555. edc_pharmacy/migrations/0005_alter_rx_managers.py +2 -1
  556. edc_pharmacy/migrations/0015_auto_20220913_2139.py +9 -22
  557. edc_pharmacy/migrations/0016_auto_20220929_1742.py +2 -1
  558. edc_pharmacy/migrations/0018_alter_rxrefill_managers.py +1 -1
  559. edc_pharmacy/migrations/0020_alter_box_device_created_alter_box_device_modified_and_more.py +71 -211
  560. edc_pharmacy/migrations/0021_alter_box_options_alter_container_options_and_more.py +1 -1
  561. edc_pharmacy/migrations/0023_remove_rx_edc_pharmac_modifie_986021_idx_and_more.py +1 -3
  562. edc_pharmacy/migrations/0024_allocation_assignment_containerunits_dispense_and_more.py +40 -104
  563. edc_pharmacy/migrations/0031_historicalrepackrequest_task_id_and_more.py +2 -1
  564. edc_pharmacy/migrations/0033_container_display_name_and_more.py +1 -3
  565. edc_pharmacy/migrations/0035_container_max_per_subject_and_more.py +2 -6
  566. edc_pharmacy/migrations/0037_remove_historicalstock_confirmed_at_site_by_and_more.py +2 -6
  567. edc_pharmacy/migrations/0039_remove_dispense_registered_subject_and_more.py +7 -9
  568. edc_pharmacy/migrations/0043_stockproxy_alter_historicallot_lot_no_and_more.py +2 -1
  569. edc_pharmacy/migrations/0049_remove_stocktransferconfirmation_stock_and_more.py +5 -13
  570. edc_pharmacy/migrations/0050_remove_stocktransferconfirmation2_location_and_more.py +2 -6
  571. edc_pharmacy/migrations/0051_alter_historicalstocktransferconfirmationitem_options_and_more.py +2 -1
  572. edc_pharmacy/migrations/0053_alter_location_managers_alter_historicalstock_lot_and_more.py +7 -11
  573. edc_pharmacy/migrations/0057_scanduplicates.py +3 -4
  574. edc_pharmacy/migrations/0058_stockrequestproxy_alter_stockproxy_options.py +2 -1
  575. edc_pharmacy/migrations/0060_alter_container_max_per_subject_and_more.py +8 -14
  576. edc_pharmacy/migrations/0061_alter_historicalstocktransferconfirmation_options_and_more.py +1 -1
  577. edc_pharmacy/migrations/0062_auto_20250312_1433.py +2 -6
  578. edc_pharmacy/migrations/0063_alter_allocation_managers_remove_allocation_site_and_more.py +2 -1
  579. edc_pharmacy/migrations/0065_allocationproxy.py +2 -1
  580. edc_pharmacy/migrations/0068_stockout.py +2 -1
  581. edc_pharmacy/migrations/0076_historicalstockadjustment_stockadjustment.py +5 -8
  582. edc_pharmacy/migrations/0077_historicalstockadjustment_adjustment_datetime_and_more.py +2 -1
  583. edc_pharmacy/migrations/0078_alter_historicalstock_qty_and_more.py +2 -1
  584. edc_pharmacy/migrations/0081_historicalconfirmation_confirmation.py +8 -10
  585. edc_pharmacy/migrations/0084_confirmationatsiteitem_and_more.py +2 -2
  586. edc_pharmacy/model_mixins/study_medication_crf_model_mixin.py +3 -9
  587. edc_pharmacy/models/medication/dosage_guideline.py +1 -3
  588. edc_pharmacy/models/medication/formulation.py +1 -3
  589. edc_pharmacy/models/prescription/rx.py +1 -3
  590. edc_pharmacy/models/prescription/rx_refill.py +2 -6
  591. edc_pharmacy/models/signals.py +11 -21
  592. edc_pharmacy/models/stock/allocation.py +3 -9
  593. edc_pharmacy/models/stock/confirmation.py +1 -3
  594. edc_pharmacy/models/stock/confirmation_at_site_item.py +1 -3
  595. edc_pharmacy/models/stock/container.py +1 -3
  596. edc_pharmacy/models/stock/dispense.py +1 -3
  597. edc_pharmacy/models/stock/dispense_item.py +1 -3
  598. edc_pharmacy/models/stock/lot.py +1 -3
  599. edc_pharmacy/models/stock/order_item.py +2 -6
  600. edc_pharmacy/models/stock/product.py +2 -6
  601. edc_pharmacy/models/stock/receive_item.py +4 -12
  602. edc_pharmacy/models/stock/repack_request.py +1 -3
  603. edc_pharmacy/models/stock/stock.py +3 -8
  604. edc_pharmacy/models/stock/stock_request_item.py +4 -4
  605. edc_pharmacy/models/stock/stock_transfer_item.py +1 -3
  606. edc_pharmacy/models/stock/supplier.py +1 -3
  607. edc_pharmacy/models/storage/utils.py +1 -4
  608. edc_pharmacy/pdf_reports/manifest_pdf_report.py +3 -9
  609. edc_pharmacy/pdf_reports/stock_pdf_report.py +3 -9
  610. edc_pharmacy/refill/adjust_previous_end_datetime.py +2 -6
  611. edc_pharmacy/refill/create_next_refill.py +1 -3
  612. edc_pharmacy/refill/create_refill.py +1 -3
  613. edc_pharmacy/refill/refill_creator.py +2 -6
  614. edc_pharmacy/sample_usb_printing/network_printers.py +1 -3
  615. edc_pharmacy/settings.py +3 -9
  616. edc_pharmacy/urls.py +1 -3
  617. edc_pharmacy/utils/allocate_stock.py +1 -3
  618. edc_pharmacy/utils/confirm_stock_at_site.py +3 -5
  619. edc_pharmacy/utils/dispense.py +1 -4
  620. edc_pharmacy/utils/get_unit_qty_out.py +1 -3
  621. edc_pharmacy/utils/process_repack_request.py +1 -3
  622. edc_pharmacy/utils/process_repack_request_queryset.py +1 -3
  623. edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -6
  624. edc_pharmacy/utils/stock_request/get_instock_and_nostock_data.py +3 -8
  625. edc_pharmacy/utils/transfer_stock.py +1 -3
  626. edc_pharmacy/utils/update_previous_refill_end_datetime.py +1 -3
  627. edc_pharmacy/views/add_to_storage_bin_view.py +2 -6
  628. edc_pharmacy/views/allocate_to_subject_view.py +7 -21
  629. edc_pharmacy/views/confirm_stock_from_instance_view.py +2 -6
  630. edc_pharmacy/views/confirm_stock_from_queryset_view.py +2 -7
  631. edc_pharmacy/views/confirmation_at_site_view.py +10 -31
  632. edc_pharmacy/views/dispense_view.py +2 -6
  633. edc_pharmacy/views/move_to_storage_bin_view.py +2 -6
  634. edc_pharmacy/views/prepare_and_review_stock_request_view.py +3 -9
  635. edc_pharmacy/views/print_labels_view.py +1 -3
  636. edc_pharmacy/views/print_stock_transfer_manifest_view.py +1 -3
  637. edc_pharmacy/views/transfer_stock_view.py +1 -3
  638. edc_prn/modelform_mixins.py +1 -3
  639. edc_prn/prn.py +2 -6
  640. edc_prn/templatetags/edc_prn_extras.py +4 -8
  641. edc_protocol/research_protocol_config.py +2 -5
  642. edc_protocol_incident/admin/protocol_deviation_violation_admin.py +1 -3
  643. edc_protocol_incident/auth_objects.py +1 -3
  644. edc_protocol_incident/auths.py +1 -3
  645. edc_protocol_incident/form_validators/mixins.py +3 -9
  646. edc_protocol_incident/form_validators/protocol_deviation_violation_form_validator.py +6 -18
  647. edc_protocol_incident/form_validators/protocol_incident_form_validator.py +3 -8
  648. edc_protocol_incident/migrations/0001_initial.py +4 -3
  649. edc_protocol_incident/migrations/0001_squashed_0015_auto_20220927_0401.py +7 -12
  650. edc_protocol_incident/migrations/0005_protocolincident_historicalprotocolincident_and_more.py +4 -3
  651. edc_protocol_incident/migrations/0012_auto_20220913_2139.py +3 -9
  652. edc_protocol_incident/migrations/0020_alter_historicalprotocoldeviationviolation_device_created_and_more.py +9 -25
  653. edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +3 -7
  654. edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +1 -3
  655. edc_protocol_incident/urls.py +1 -3
  656. edc_pylabels/actions.py +2 -6
  657. edc_pylabels/admin/label_configuration_admin.py +4 -4
  658. edc_pylabels/drawing_callable_example.py +1 -3
  659. edc_pylabels/migrations/0001_initial.py +1 -3
  660. edc_pylabels/migrations/0002_alter_label_options_label_created_and_more.py +2 -6
  661. edc_pylabels/migrations/0005_labelconfiguration_delete_label_and_more.py +1 -3
  662. edc_pylabels/models/label_configuration.py +1 -3
  663. edc_qareports/migrations/0001_initial.py +3 -4
  664. edc_qareports/migrations/0005_edcpermissions.py +2 -4
  665. edc_qareports/migrations/0006_qareportlog.py +2 -1
  666. edc_qareports/migrations/0007_qareportlog_edc_qarepor_accesse_738ffe_idx.py +1 -3
  667. edc_qareports/migrations/0017_auto_20240816_0256.py +1 -0
  668. edc_qareports/model_mixins/note_model_mixin.py +1 -3
  669. edc_qareports/modeladmin_mixins/list_filters.py +8 -12
  670. edc_qareports/modeladmin_mixins/note_modeladmin_mixin.py +1 -3
  671. edc_qareports/modeladmin_mixins/on_study_missing_values_modeladmin_mixin.py +2 -6
  672. edc_qareports/modeladmin_mixins/qa_report_modeladmin_mixin.py +1 -3
  673. edc_qareports/sql_generator/crf_case.py +1 -5
  674. edc_qareports/sql_generator/sql_view_generator.py +1 -3
  675. edc_qareports/utils.py +2 -6
  676. edc_randomization/admin.py +1 -3
  677. edc_randomization/auths.py +2 -6
  678. edc_randomization/blinding.py +1 -3
  679. edc_randomization/migrations/0001_initial.py +3 -4
  680. edc_randomization/migrations/0009_edcpermissions.py +1 -1
  681. edc_randomization/migrations/0011_alter_edcpermissions_device_created_and_more.py +7 -19
  682. edc_randomization/model_mixins.py +2 -5
  683. edc_randomization/randomization_list_importer.py +3 -7
  684. edc_randomization/randomization_list_verifier.py +2 -7
  685. edc_randomization/randomizer.py +2 -6
  686. edc_randomization/site_randomizers.py +1 -3
  687. edc_randomization/system_checks.py +1 -3
  688. edc_randomization/utils.py +2 -6
  689. edc_refusal/admin.py +1 -3
  690. edc_refusal/forms.py +1 -2
  691. edc_refusal/migrations/0001_initial.py +2 -1
  692. edc_refusal/migrations/0002_historicalsubjectrefusal.py +6 -4
  693. edc_refusal/migrations/0004_refusalreasons_plural_name.py +1 -3
  694. edc_refusal/migrations/0005_alter_subjectrefusal_options_and_more.py +2 -1
  695. edc_refusal/migrations/0006_alter_subjectrefusal_managers.py +2 -1
  696. edc_refusal/migrations/0008_alter_historicalsubjectrefusal_device_created_and_more.py +5 -13
  697. edc_registration/admin_site.py +1 -3
  698. edc_registration/migrations/0001_initial.py +3 -4
  699. edc_registration/migrations/0002_auto_20161127_2226.py +4 -7
  700. edc_registration/migrations/0004_auto_20161221_0018.py +2 -1
  701. edc_registration/migrations/0005_auto_20170111_1809.py +2 -1
  702. edc_registration/migrations/0008_auto_20170810_1032.py +2 -1
  703. edc_registration/migrations/0012_auto_20180116_1528.py +2 -1
  704. edc_registration/migrations/0015_auto_20181006_2257.py +1 -1
  705. edc_registration/migrations/0016_historicalregisteredsubject.py +5 -6
  706. edc_registration/migrations/0026_historicalregisteredsubject_familiar_name_and_more.py +1 -1
  707. edc_registration/migrations/0028_alter_registeredsubject_managers.py +1 -1
  708. edc_registration/migrations/0029_alter_historicalregisteredsubject_device_created_and_more.py +5 -13
  709. edc_registration/modeladmin_mixins.py +1 -3
  710. edc_registration/models/registered_subject.py +4 -11
  711. edc_registration/utils.py +1 -3
  712. edc_reportable/admin_site.py +1 -3
  713. edc_reportable/data/normal_data/africa.py +4 -14
  714. edc_reportable/evaluator.py +2 -6
  715. edc_reportable/formula.py +2 -6
  716. edc_reportable/management/commands/export_reportables.py +1 -3
  717. edc_reportable/migrations/0001_initial.py +3 -9
  718. edc_reportable/migrations/0003_referencerangecollection_grade1_and_more.py +3 -9
  719. edc_reportable/migrations/0004_alter_referencerangecollection_grade3_and_more.py +4 -7
  720. edc_reportable/migrations/0006_alter_gradingdata_revision_and_more.py +8 -19
  721. edc_reportable/models/mw.py +1 -3
  722. edc_reportable/models/reference_model_mixins.py +1 -3
  723. edc_reportable/models/reference_range_collection.py +3 -9
  724. edc_reportable/post_migrate_signals.py +1 -3
  725. edc_reportable/reference_range_evaluator.py +4 -11
  726. edc_reportable/utils/convert_units.py +1 -3
  727. edc_reportable/utils/get_grade_for_value.py +3 -1
  728. edc_reportable/utils/get_reference_range_collection.py +2 -2
  729. edc_reportable/utils/load_data.py +1 -3
  730. edc_reportable/utils/update_grading_data.py +2 -6
  731. edc_review_dashboard/migrations/0001_initial.py +1 -1
  732. edc_review_dashboard/migrations/0003_alter_edcpermissions_device_created_and_more.py +3 -7
  733. edc_review_dashboard/views/subject_review_listboard_view.py +1 -3
  734. edc_screening/eligibility.py +1 -3
  735. edc_screening/fc.py +1 -3
  736. edc_screening/migrations/0001_initial.py +1 -1
  737. edc_screening/migrations/0002_alter_edcpermissions_device_created_and_more.py +3 -7
  738. edc_screening/model_mixins/eligibility_model_mixin.py +1 -3
  739. edc_screening/model_mixins/screening_fields_model_mixin.py +2 -0
  740. edc_screening/modelform_mixins.py +1 -3
  741. edc_search/search_slug.py +2 -6
  742. edc_search/updater.py +2 -5
  743. edc_sites/admin/site_model_admin_mixin.py +4 -12
  744. edc_sites/management/commands/sync_sites.py +1 -3
  745. edc_sites/migrations/0007_edcpermissions.py +2 -4
  746. edc_sites/single_site/get_languages.py +1 -3
  747. edc_sites/site.py +4 -11
  748. edc_sites/system_checks.py +1 -4
  749. edc_sites/utils/add_or_update_django_sites.py +1 -3
  750. edc_subject_dashboard/migrations/0001_initial.py +1 -1
  751. edc_subject_dashboard/migrations/0002_alter_edcpermissions_device_created_and_more.py +3 -7
  752. edc_subject_dashboard/requisition_labels.py +1 -3
  753. edc_subject_dashboard/requisition_report.py +5 -15
  754. edc_subject_dashboard/requisition_verifier.py +2 -7
  755. edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +2 -6
  756. edc_subject_dashboard/view_mixins/subject_visit_view_mixin.py +1 -2
  757. edc_subject_dashboard/view_utils/crf_button.py +1 -3
  758. edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +1 -3
  759. edc_subject_dashboard/view_utils/timepoint_status_button.py +1 -3
  760. edc_subject_dashboard/views/requisition_print_actions_view.py +4 -12
  761. edc_subject_dashboard/views/requisition_verify_actions_view.py +1 -3
  762. edc_subject_dashboard/views/subject_dashboard_view.py +1 -3
  763. edc_timepoint/apps.py +1 -3
  764. edc_timepoint/timepoint.py +1 -3
  765. edc_timepoint/timepoint_lookup.py +1 -3
  766. edc_transfer/form_validators.py +4 -6
  767. edc_transfer/model_mixins.py +1 -3
  768. edc_transfer/modelform_mixins.py +1 -3
  769. edc_unblinding/action_items.py +1 -3
  770. edc_unblinding/admin_site.py +1 -3
  771. edc_unblinding/migrations/0001_initial.py +6 -4
  772. edc_unblinding/migrations/0002_auto_20210908_2318.py +1 -1
  773. edc_unblinding/migrations/0009_alter_unblindingrequest_managers_and_more.py +2 -1
  774. edc_unblinding/migrations/0010_alter_historicalunblindingrequest_device_created_and_more.py +9 -25
  775. edc_unblinding/models/unblinding_request.py +1 -3
  776. edc_unblinding/models/unblinding_review.py +1 -3
  777. edc_utils/age.py +1 -3
  778. edc_utils/date.py +1 -3
  779. edc_utils/paths_for_urlpatterns.py +1 -3
  780. edc_utils/show_urls.py +1 -3
  781. edc_utils/text.py +1 -2
  782. edc_view_utils/model_button.py +5 -13
  783. edc_view_utils/query_button.py +1 -3
  784. edc_visit_schedule/admin/subject_schedule_history_admin.py +1 -3
  785. edc_visit_schedule/baseline.py +1 -3
  786. edc_visit_schedule/migrations/0001_initial.py +3 -4
  787. edc_visit_schedule/migrations/0003_historicalvisitschedule_visitschedule.py +1 -3
  788. edc_visit_schedule/migrations/0004_auto_20190629_1800.py +1 -3
  789. edc_visit_schedule/migrations/0011_alter_historicalvisitschedule_device_created_and_more.py +7 -19
  790. edc_visit_schedule/migrations/0012_alter_subjectschedulehistory_managers_and_more.py +2 -1
  791. edc_visit_schedule/migrations/0015_historicalonschedule_offschedule_onschedule.py +9 -13
  792. edc_visit_schedule/migrations/0017_alter_onschedule_managers.py +2 -1
  793. edc_visit_schedule/model_mixins/crf/crf_schedule_model_mixin.py +1 -1
  794. edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +2 -6
  795. edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +1 -3
  796. edc_visit_schedule/modelform_mixins/off_schedule_modelform_mixin.py +1 -3
  797. edc_visit_schedule/models/subject_schedule_history.py +3 -8
  798. edc_visit_schedule/ordered_collection.py +1 -3
  799. edc_visit_schedule/schedule/schedule.py +6 -17
  800. edc_visit_schedule/simple_model_validator.py +3 -8
  801. edc_visit_schedule/site_visit_schedules.py +5 -15
  802. edc_visit_schedule/subject_schedule.py +4 -16
  803. edc_visit_schedule/system_checks.py +1 -3
  804. edc_visit_schedule/utils.py +8 -17
  805. edc_visit_schedule/view_mixins.py +4 -10
  806. edc_visit_schedule/visit/crf.py +1 -2
  807. edc_visit_schedule/visit/requisition.py +1 -3
  808. edc_visit_schedule/visit/visit.py +6 -16
  809. edc_visit_schedule/visit/window_period.py +3 -3
  810. edc_visit_schedule/visit_schedule/visit_schedule.py +2 -5
  811. edc_visit_tracking/crf_date_validator.py +1 -2
  812. edc_visit_tracking/form_validators/visit_form_validator.py +2 -8
  813. edc_visit_tracking/form_validators/visit_missed_form_validator.py +3 -9
  814. edc_visit_tracking/migrations/0003_auto_20220913_2139.py +2 -6
  815. edc_visit_tracking/migrations/0004_subjectvisit_subjectvisitmissedreasons_extra_value_and_more.py +8 -16
  816. edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +2 -6
  817. edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +1 -3
  818. edc_visit_tracking/model_mixins/requisitions/visit_tracking_requisition_model_mixin.py +1 -3
  819. edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +1 -3
  820. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_fields_mixin.py +1 -2
  821. edc_visit_tracking/modeladmin_mixins/crf_model_admin_mixin.py +4 -8
  822. edc_visit_tracking/modeladmin_mixins/visit_model_admin_mixin.py +4 -6
  823. edc_visit_tracking/modelform_mixins/crf/visit_tracking_crf_modelform_mixin.py +2 -6
  824. edc_visit_tracking/modelform_mixins/utils.py +1 -3
  825. edc_visit_tracking/modelform_mixins/visit_tracking_modelform_mixin.py +1 -2
  826. edc_visit_tracking/models/signals.py +1 -3
  827. edc_visit_tracking/stubs.py +1 -3
  828. edc_visit_tracking/utils.py +1 -2
  829. edc_visit_tracking/view_utils/related_visit_button.py +1 -3
  830. edc_visit_tracking/visit_sequence.py +1 -3
  831. edc_vitals/__init__.py +2 -0
  832. edc_vitals/apps.py +6 -0
  833. edc_vitals/calculators/__init__.py +1 -0
  834. edc_vitals/calculators/bmi.py +70 -0
  835. edc_vitals/form_validators/__init__.py +5 -0
  836. edc_vitals/form_validators/blood_pressure_form_validator_mixin.py +40 -0
  837. edc_vitals/form_validators/bmi_form_validator_mixin.py +19 -0
  838. edc_vitals/form_validators/weight_height_with_bmi_form_validator_mixin.py +13 -0
  839. edc_vitals/migrations/__init__.py +0 -0
  840. edc_vitals/model_mixins/__init__.py +5 -0
  841. edc_vitals/model_mixins/blood_pressure_model_mixin.py +80 -0
  842. edc_vitals/model_mixins/weight_height_bmi_model_mixin.py +42 -0
  843. edc_vitals/models/__init__.py +10 -0
  844. edc_vitals/models/fields/__init__.py +7 -0
  845. edc_vitals/models/fields/blood_pressure.py +36 -0
  846. edc_vitals/models/fields/heart_rate.py +22 -0
  847. edc_vitals/models/fields/height.py +26 -0
  848. edc_vitals/models/fields/respiratory_rate.py +22 -0
  849. edc_vitals/models/fields/temperature.py +26 -0
  850. edc_vitals/models/fields/waist_circumference.py +23 -0
  851. edc_vitals/models/fields/weight.py +26 -0
  852. edc_vitals/utils.py +51 -0
  853. edc_vitals/validators.py +5 -0
  854. edc_lab_results/model_mixin_factory/__init__.py +0 -2
  855. {clinicedc-2.0.1.dist-info → clinicedc-2.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -23,9 +23,7 @@ if TYPE_CHECKING:
23
23
 
24
24
  from .consent_definition import ConsentDefinition
25
25
 
26
- class ConsentLikeModel(
27
- SiteModelMixin, UniqueSubjectIdentifierModelMixin, BaseUuidModel
28
- ):
26
+ class ConsentLikeModel(SiteModelMixin, UniqueSubjectIdentifierModelMixin, BaseUuidModel):
29
27
  _meta: ...
30
28
 
31
29
  class ConsentExtensionLikeModel(
@@ -59,9 +57,7 @@ class ConsentDefinitionExtension:
59
57
 
60
58
  model: str = field(compare=False)
61
59
  _ = KW_ONLY
62
- start: datetime = field(
63
- default=ResearchProtocolConfig().study_open_datetime, compare=True
64
- )
60
+ start: datetime = field(default=ResearchProtocolConfig().study_open_datetime, compare=True)
65
61
  version: str = field(default="1", compare=False)
66
62
  extends: ConsentDefinition = field(default=None, compare=False)
67
63
  timepoints: list[int] | None = field(default_factory=list, compare=False)
@@ -75,9 +71,7 @@ class ConsentDefinitionExtension:
75
71
  self.name = f"{self.model}-{self.version}"
76
72
  self.sort_index = self.name
77
73
  if not self.start.tzinfo:
78
- raise ConsentDefinitionError(
79
- f"Naive datetime not allowed. Got {self.start}."
80
- )
74
+ raise ConsentDefinitionError(f"Naive datetime not allowed. Got {self.start}.")
81
75
  elif str(self.start.tzinfo) != "UTC":
82
76
  raise ConsentDefinitionError(f"Start date must be UTC. Got {self.start}.")
83
77
  self.extends.check_date_within_study_period()
@@ -118,9 +112,7 @@ class ConsentDefinitionExtension:
118
112
  if self.country:
119
113
  sites = site_sites.get_by_country(self.country, aslist=True)
120
114
  elif self.site_ids:
121
- sites = [
122
- s for s in site_sites.all(aslist=True) if s.site_id in self.site_ids
123
- ]
115
+ sites = [s for s in site_sites.all(aslist=True) if s.site_id in self.site_ids]
124
116
  else:
125
117
  sites = [s for s in site_sites.all(aslist=True)]
126
118
  return sites
@@ -13,8 +13,7 @@ class CitizenFieldsMixin(models.Model):
13
13
 
14
14
  legal_marriage = models.CharField(
15
15
  verbose_name=(
16
- "If not a citizen, is the participant legally "
17
- "married to a Botswana citizen?"
16
+ "If not a citizen, is the participant legally " "married to a Botswana citizen?"
18
17
  ),
19
18
  max_length=3,
20
19
  choices=YES_NO_NA,
@@ -26,8 +25,7 @@ class CitizenFieldsMixin(models.Model):
26
25
 
27
26
  marriage_certificate = models.CharField(
28
27
  verbose_name=(
29
- "[Interviewer] Has the participant produced "
30
- "the marriage certificate as proof? "
28
+ "[Interviewer] Has the participant produced " "the marriage certificate as proof? "
31
29
  ),
32
30
  max_length=3,
33
31
  choices=YES_NO_NA,
@@ -36,8 +36,7 @@ class IdentityFieldsMixin(CryptoMixin, models.Model):
36
36
  def save(self, *args, **kwargs):
37
37
  if self.identity != self.confirm_identity:
38
38
  raise IdentityFieldsMixinError(
39
- "'Identity' must match 'confirm_identity'. "
40
- "Catch this error on the form"
39
+ "'Identity' must match 'confirm_identity'. " "Catch this error on the form"
41
40
  )
42
41
  super().save(*args, **kwargs)
43
42
 
@@ -35,12 +35,17 @@ class BaseFieldsMixin(models.Model):
35
35
  help_text=format_html(
36
36
  "{text1}.<BR>{text2}",
37
37
  text1=_("Required only if participant is a minor"),
38
- text2=_(
39
- "Format is 'LASTNAME, FIRSTNAME'. All uppercase separated by a comma."
40
- ),
38
+ text2=_("Format is 'LASTNAME, FIRSTNAME'. All uppercase separated by a comma."),
41
39
  ),
42
40
  )
43
41
 
42
+ ethnicity = models.CharField(
43
+ max_length=15,
44
+ help_text=_("from screening"),
45
+ editable=False,
46
+ null=True,
47
+ )
48
+
44
49
  subject_type = models.CharField(max_length=25)
45
50
 
46
51
  class Meta:
@@ -6,8 +6,7 @@ class SiteFieldsMixin(models.Model):
6
6
  verbose_name="Site",
7
7
  max_length=25,
8
8
  help_text=(
9
- "This refers to the site or 'clinic area' where the "
10
- "subject is being consented."
9
+ "This refers to the site or 'clinic area' where the " "subject is being consented."
11
10
  ),
12
11
  )
13
12
 
@@ -63,9 +63,7 @@ class SubjectConsentFormValidatorMixin(SubjectScreeningFormValidatorMixin):
63
63
  self.raise_validation_error(
64
64
  {"consent_datetime": "This field is required."}, INVALID_ERROR
65
65
  )
66
- self._consent_datetime = to_utc(
67
- self.cleaned_data.get("consent_datetime")
68
- )
66
+ self._consent_datetime = to_utc(self.cleaned_data.get("consent_datetime"))
69
67
  else:
70
68
  self._consent_datetime = self.instance.consent_datetime
71
69
  return self._consent_datetime
@@ -82,10 +80,7 @@ class SubjectConsentFormValidatorMixin(SubjectScreeningFormValidatorMixin):
82
80
 
83
81
  def validate_age(self) -> None:
84
82
  """Validate age matches that on the screening form."""
85
- if (
86
- self.dob
87
- and self.screening_age_in_years != self.subject_screening.age_in_years
88
- ):
83
+ if self.dob and self.screening_age_in_years != self.subject_screening.age_in_years:
89
84
  self.raise_validation_error(
90
85
  {
91
86
  "dob": "Age mismatch. The date of birth entered does "
@@ -1,12 +1,12 @@
1
1
  # Generated by Django 3.2.13 on 2022-08-25 01:51
2
2
 
3
3
  import _socket
4
- from django.db import migrations, models
5
4
  import django_audit_fields.fields.hostname_modification_field
6
5
  import django_audit_fields.fields.userfield
7
6
  import django_audit_fields.fields.uuid_auto_field
8
7
  import django_audit_fields.models.audit_model_mixin
9
8
  import django_revision.revision_field
9
+ from django.db import migrations, models
10
10
 
11
11
 
12
12
  class Migration(migrations.Migration):
@@ -1,8 +1,8 @@
1
1
  # Generated by Django 4.2.4 on 2023-08-23 01:13
2
2
 
3
3
  import _socket
4
- from django.db import migrations, models
5
4
  import django_audit_fields.fields.hostname_modification_field
5
+ from django.db import migrations, models
6
6
 
7
7
 
8
8
  class Migration(migrations.Migration):
@@ -14,16 +14,12 @@ class Migration(migrations.Migration):
14
14
  migrations.AlterField(
15
15
  model_name="edcpermissions",
16
16
  name="device_created",
17
- field=models.CharField(
18
- blank=True, max_length=10, verbose_name="Device created"
19
- ),
17
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device created"),
20
18
  ),
21
19
  migrations.AlterField(
22
20
  model_name="edcpermissions",
23
21
  name="device_modified",
24
- field=models.CharField(
25
- blank=True, max_length=10, verbose_name="Device modified"
26
- ),
22
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device modified"),
27
23
  ),
28
24
  migrations.AlterField(
29
25
  model_name="edcpermissions",
@@ -30,9 +30,7 @@ class ConsentExtensionModelMixin(UniqueSubjectIdentifierModelMixin, models.Model
30
30
  help_text=_("See above for the definition of extended followup."),
31
31
  )
32
32
 
33
- comment = EncryptedTextField(
34
- verbose_name="Comment", max_length=250, blank=True, null=True
35
- )
33
+ comment = EncryptedTextField(verbose_name="Comment", max_length=250, blank=True, null=True)
36
34
 
37
35
  consent_extension_version = models.CharField(
38
36
  verbose_name="Consent extension version",
@@ -16,17 +16,13 @@ from ..managers import ConsentObjectsManager
16
16
  from .consent_version_model_mixin import ConsentVersionModelMixin
17
17
 
18
18
 
19
- class ConsentModelMixin(
20
- ConsentVersionModelMixin, VerificationFieldsMixin, models.Model
21
- ):
19
+ class ConsentModelMixin(ConsentVersionModelMixin, VerificationFieldsMixin, models.Model):
22
20
  """Mixin for a Consent model class such as SubjectConsent.
23
21
 
24
22
  Declare with edc_identifier's NonUniqueSubjectIdentifierModelMixin
25
23
  """
26
24
 
27
- screening_identifier = models.CharField(
28
- verbose_name="Screening identifier", max_length=50
29
- )
25
+ screening_identifier = models.CharField(verbose_name="Screening identifier", max_length=50)
30
26
 
31
27
  screening_datetime = models.DateTimeField(
32
28
  verbose_name="Screening datetime", null=True, editable=False
@@ -59,9 +55,7 @@ class ConsentModelMixin(
59
55
  help_text="Used for randomization against a prepared rando-list.",
60
56
  )
61
57
 
62
- comment = EncryptedTextField(
63
- verbose_name="Comment", max_length=250, blank=True, null=True
64
- )
58
+ comment = EncryptedTextField(verbose_name="Comment", max_length=250, blank=True, null=True)
65
59
 
66
60
  dm_comment = models.CharField(
67
61
  verbose_name="Data Management comment",
@@ -70,9 +70,7 @@ class ConsentModelAdminMixin:
70
70
  fields = ("subject_identifier", "subject_identifier_as_pk")
71
71
  if obj:
72
72
  return (
73
- fields
74
- + ("consent_datetime", "identity", "confirm_identity")
75
- + readonly_fields
73
+ fields + ("consent_datetime", "identity", "confirm_identity") + readonly_fields
76
74
  )
77
75
  else:
78
76
  return fields + readonly_fields
@@ -131,16 +129,12 @@ class ConsentModelAdminMixin:
131
129
  def delete_view(self, request, object_id, extra_context=None):
132
130
  """Prevent deletion if SubjectVisit objects exist."""
133
131
  extra_context = extra_context or {}
134
- subject_consent_model_cls = django_apps.get_model(
135
- settings.SUBJECT_CONSENT_MODEL
136
- )
132
+ subject_consent_model_cls = django_apps.get_model(settings.SUBJECT_CONSENT_MODEL)
137
133
  related_visit_model_cls = django_apps.get_model(settings.SUBJECT_VISIT_MODEL)
138
134
  obj = subject_consent_model_cls.objects.get(id=object_id)
139
135
  try:
140
136
  protected = [
141
- related_visit_model_cls.objects.get(
142
- subject_identifier=obj.subject_identifier
143
- )
137
+ related_visit_model_cls.objects.get(subject_identifier=obj.subject_identifier)
144
138
  ]
145
139
  except ObjectDoesNotExist:
146
140
  protected = None
@@ -155,18 +149,14 @@ class ConsentModelAdminMixin:
155
149
  """Returns the key/value pairs from the "next" querystring
156
150
  as a dictionary.
157
151
  """
158
- subject_screening_model_cls = django_apps.get_model(
159
- settings.SUBJECT_SCREENING_MODEL
160
- )
152
+ subject_screening_model_cls = django_apps.get_model(settings.SUBJECT_SCREENING_MODEL)
161
153
  next_options = super().get_next_options(request=request, **kwargs)
162
154
  try:
163
155
  is_subject_identifier_or_raise(next_options["subject_identifier"])
164
156
  except SubjectIdentifierError:
165
- next_options["subject_identifier"] = (
166
- subject_screening_model_cls.objects.get(
167
- subject_identifier_as_pk=next_options["subject_identifier"]
168
- ).subject_identifier
169
- )
157
+ next_options["subject_identifier"] = subject_screening_model_cls.objects.get(
158
+ subject_identifier_as_pk=next_options["subject_identifier"]
159
+ ).subject_identifier
170
160
  except KeyError:
171
161
  pass
172
162
  return next_options
@@ -54,9 +54,7 @@ class ConsentModelFormValidationMixin:
54
54
 
55
55
  @property
56
56
  def consent_datetime(self) -> datetime:
57
- return self.get_field_or_raise(
58
- "consent_datetime", "Consent date and time is required"
59
- )
57
+ return self.get_field_or_raise("consent_datetime", "Consent date and time is required")
60
58
 
61
59
  @property
62
60
  def identity(self) -> str:
@@ -64,9 +62,7 @@ class ConsentModelFormValidationMixin:
64
62
 
65
63
  @property
66
64
  def confirm_identity(self) -> str:
67
- return self.get_field_or_raise(
68
- "confirm_identity", "Confirmed identity is required"
69
- )
65
+ return self.get_field_or_raise("confirm_identity", "Confirmed identity is required")
70
66
 
71
67
  @property
72
68
  def age_delta(self) -> relativedelta | None:
@@ -193,8 +189,7 @@ class ConsentModelFormValidationMixin:
193
189
  gender = self.cleaned_data.get("gender")
194
190
  if gender not in self.consent_definition.gender:
195
191
  raise forms.ValidationError(
196
- "Gender of consent can only be "
197
- "'%(gender_of_consent)s'. Got '%(gender)s'.",
192
+ "Gender of consent can only be " "'%(gender_of_consent)s'. Got '%(gender)s'.",
198
193
  params={
199
194
  "gender_of_consent": "' or '".join(self.consent_definition.gender),
200
195
  "gender": gender,
@@ -38,9 +38,7 @@ class RequiresConsentModelFormMixin:
38
38
  def validate_against_dob(self, consent_obj):
39
39
  if consent_obj and to_utc(self.report_datetime).date() < consent_obj.dob:
40
40
  dte_str = formatted_date(consent_obj.dob)
41
- raise forms.ValidationError(
42
- f"Report datetime cannot be before DOB. Got {dte_str}"
43
- )
41
+ raise forms.ValidationError(f"Report datetime cannot be before DOB. Got {dte_str}")
44
42
 
45
43
  def validate_against_consent(self) -> ConsentLikeModel | None:
46
44
  """Raise an exception if the report datetime doesn't make
@@ -17,9 +17,7 @@ def requires_consent_on_pre_save(instance, raw, using, update_fields, **kwargs):
17
17
  and isinstance(instance, (RequiresConsentFieldsModelMixin,))
18
18
  and not instance._meta.model_name.startswith("historical")
19
19
  ):
20
- subject_identifier = getattr(
21
- instance, "related_visit", instance
22
- ).subject_identifier
20
+ subject_identifier = getattr(instance, "related_visit", instance).subject_identifier
23
21
  site = getattr(instance, "related_visit", instance).site
24
22
  try:
25
23
  schedule = getattr(instance, "related_visit", instance).schedule
@@ -68,9 +66,7 @@ def update_appointment_from_consentext_post_save(
68
66
  model=instance.subject_consent._meta.label_lower,
69
67
  version=instance.subject_consent.version,
70
68
  )
71
- visit_schedule, schedule = site_visit_schedules.get_by_consent_definition(
72
- cdef
73
- )
69
+ visit_schedule, schedule = site_visit_schedules.get_by_consent_definition(cdef)
74
70
  subject_schedule = SubjectSchedule(
75
71
  instance.subject_consent.subject_identifier,
76
72
  visit_schedule=visit_schedule,
@@ -45,9 +45,7 @@ class SiteConsents:
45
45
  cdef.updated_by = updated_by
46
46
  cdef.extended_by = extended_by
47
47
  if cdef.name in self.registry:
48
- raise AlreadyRegistered(
49
- f"Consent definition already registered. Got {cdef.name}."
50
- )
48
+ raise AlreadyRegistered(f"Consent definition already registered. Got {cdef.name}.")
51
49
  self.validate_period_overlap_or_raise(cdef)
52
50
  self.validate_updates_or_raise(cdef)
53
51
  self.registry.update({cdef.name: cdef})
@@ -166,11 +164,7 @@ class SiteConsents:
166
164
  f"'{consent_definition.version}' "
167
165
  f"of consent on or after report_datetime='{dte}'?"
168
166
  )
169
- elif (
170
- consent_definition.start
171
- <= to_utc(report_datetime)
172
- <= consent_definition.end
173
- ):
167
+ elif consent_definition.start <= to_utc(report_datetime) <= consent_definition.end:
174
168
  # ensures the higher version is returned if there is overlap
175
169
  pass
176
170
  elif (
@@ -251,9 +245,7 @@ class SiteConsents:
251
245
 
252
246
  # filter cdefs to try to get just one.
253
247
  # by model, report_datetime, version, site
254
- cdefs, error_msg = self._filter_cdefs_by_model_or_raise(
255
- model, cdefs, error_messages
256
- )
248
+ cdefs, error_msg = self._filter_cdefs_by_model_or_raise(model, cdefs, error_messages)
257
249
  cdefs, error_msg = self._filter_cdefs_by_report_datetime_or_raise(
258
250
  report_datetime, cdefs, error_messages
259
251
  )
@@ -334,9 +326,7 @@ class SiteConsents:
334
326
  cdefs = [
335
327
  cdef
336
328
  for cdef in cdefs
337
- if floor_secs(cdef.start)
338
- <= to_utc(report_datetime)
339
- <= ceil_secs(cdef.end)
329
+ if floor_secs(cdef.start) <= to_utc(report_datetime) <= ceil_secs(cdef.end)
340
330
  ]
341
331
  if not cdefs:
342
332
  date_string = formatted_date(report_datetime)
@@ -411,9 +401,7 @@ class SiteConsents:
411
401
  try:
412
402
  before_import_registry = deepcopy(site_consents.registry)
413
403
  import_module(f"{app}.{module_name}")
414
- writer(
415
- f" * registered consent definitions '{module_name}' from '{app}'\n"
416
- )
404
+ writer(f" * registered consent definitions '{module_name}' from '{app}'\n")
417
405
  except SiteConsentError as e:
418
406
  writer(f" - loading {app}.consents ... ")
419
407
  writer(style.ERROR(f"ERROR! {e}\n"))
@@ -79,9 +79,7 @@ def check_consents_durations() -> list[CheckMessage]:
79
79
  for cdef2 in cdefs:
80
80
  if cdef1 == cdef2:
81
81
  continue
82
- err, found = _inspect_possible_overlap_in_validity_period(
83
- cdef1, cdef2, found
84
- )
82
+ err, found = _inspect_possible_overlap_in_validity_period(cdef1, cdef2, found)
85
83
  if err:
86
84
  errors.append(err)
87
85
  return errors
@@ -99,13 +97,9 @@ def _inspect_possible_overlap_in_validity_period(
99
97
  err = None
100
98
  if (
101
99
  cdef1.model_cls._meta.proxy
102
- and cdef1.model_cls._meta.proxy_for_model
103
- == cdef1.model_cls._meta.proxy_for_model
100
+ and cdef1.model_cls._meta.proxy_for_model == cdef1.model_cls._meta.proxy_for_model
104
101
  ):
105
- if (
106
- cdef1.start <= cdef2.start <= cdef1.end
107
- or cdef1.start <= cdef2.end <= cdef1.end
108
- ):
102
+ if cdef1.start <= cdef2.start <= cdef1.end or cdef1.start <= cdef2.end <= cdef1.end:
109
103
  if sorted([cdef1, cdef2], key=lambda x: x.version) in found:
110
104
  pass
111
105
  else:
edc_consent/validators.py CHANGED
@@ -14,8 +14,7 @@ class SubjectTypeValidator:
14
14
  def __call__(self, value):
15
15
  if value not in self.subject_types:
16
16
  raise ValidationError(
17
- "Undefined subject type. Expected one of '{subject_types}'. "
18
- "Got '{value}'.",
17
+ "Undefined subject type. Expected one of '{subject_types}'. " "Got '{value}'.",
19
18
  params={
20
19
  "subject_types": "' or '".join(self.subject_types),
21
20
  "value": value,
@@ -76,10 +76,8 @@ class ConsentViewMixin:
76
76
  site=site_sites.get(self.request.site.id),
77
77
  )
78
78
  elif self.appointment:
79
- self._consent_definition = (
80
- self.appointment.schedule.get_consent_definition(
81
- report_datetime=self.appointment.appt_datetime,
82
- site=site_sites.get(self.appointment.site.id),
83
- )
79
+ self._consent_definition = self.appointment.schedule.get_consent_definition(
80
+ report_datetime=self.appointment.appt_datetime,
81
+ site=site_sites.get(self.appointment.site.id),
84
82
  )
85
83
  return self._consent_definition
@@ -72,9 +72,7 @@ class CrfFormValidator(
72
72
  fldname="report_datetime",
73
73
  )
74
74
  if floor_secs(report_datetime) < floor_secs(consent_datetime):
75
- msg = _(
76
- "Invalid. Cannot be before date of consent. Participant consented on"
77
- )
75
+ msg = _("Invalid. Cannot be before date of consent. Participant consented on")
78
76
  formatted_date = formatted_datetime(to_local(consent_datetime))
79
77
  err_message = format_lazy(
80
78
  "{msg} {formatted_date}", msg=msg, formatted_date=formatted_date
@@ -100,9 +98,7 @@ class CrfFormValidator(
100
98
  msg = _("is required")
101
99
  verbose_name = self.related_visit._meta.verbose_name
102
100
  self.raise_validation_error(
103
- format_lazy(
104
- "{verbose_name} {msg}.", msg=msg, verbose_name=verbose_name
105
- ),
101
+ format_lazy("{verbose_name} {msg}.", msg=msg, verbose_name=verbose_name),
106
102
  INVALID_ERROR,
107
103
  )
108
104
 
@@ -18,9 +18,7 @@ if TYPE_CHECKING:
18
18
  from edc_sites.model_mixins import SiteModelMixin
19
19
  from edc_visit_tracking.model_mixins import VisitModelMixin as Base
20
20
 
21
- class RelatedVisitModel(
22
- SiteModelMixin, CreatesMetadataModelMixin, Base, BaseUuidModel
23
- ):
21
+ class RelatedVisitModel(SiteModelMixin, CreatesMetadataModelMixin, Base, BaseUuidModel):
24
22
  pass
25
23
 
26
24
 
@@ -82,9 +80,7 @@ class CrfFormValidatorMixin(BaseFormValidatorMixin):
82
80
  @property
83
81
  def related_visit(self) -> RelatedVisitModel:
84
82
  """Returns a subject visit model instance or None"""
85
- return get_related_visit(
86
- self, related_visit_model_attr=self.related_visit_model_attr
87
- )
83
+ return get_related_visit(self, related_visit_model_attr=self.related_visit_model_attr)
88
84
 
89
85
  @property
90
86
  def related_visit_model_cls(self) -> Type[RelatedVisitModel]:
@@ -1,8 +1,8 @@
1
1
  # Generated by Django 4.2.4 on 2023-08-23 01:13
2
2
 
3
3
  import _socket
4
- from django.db import migrations, models
5
4
  import django_audit_fields.fields.hostname_modification_field
5
+ from django.db import migrations, models
6
6
 
7
7
 
8
8
  class Migration(migrations.Migration):
@@ -14,16 +14,12 @@ class Migration(migrations.Migration):
14
14
  migrations.AlterField(
15
15
  model_name="crfstatus",
16
16
  name="device_created",
17
- field=models.CharField(
18
- blank=True, max_length=10, verbose_name="Device created"
19
- ),
17
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device created"),
20
18
  ),
21
19
  migrations.AlterField(
22
20
  model_name="crfstatus",
23
21
  name="device_modified",
24
- field=models.CharField(
25
- blank=True, max_length=10, verbose_name="Device modified"
26
- ),
22
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device modified"),
27
23
  ),
28
24
  migrations.AlterField(
29
25
  model_name="crfstatus",
edc_crf/utils.py CHANGED
@@ -55,9 +55,7 @@ class HasCrfChecker:
55
55
  except ObjectDoesNotExist:
56
56
  pass
57
57
  except MultipleObjectsReturned:
58
- raise MultipleObjectsReturned(
59
- "Specify the visit_code and visit_code_sequence"
60
- )
58
+ raise MultipleObjectsReturned("Specify the visit_code and visit_code_sequence")
61
59
  else:
62
60
  for model in self.models:
63
61
  if model.objects.filter(subject_visit=subject_visit).exists():
@@ -42,9 +42,7 @@ class Command(BaseCommand):
42
42
  if "update_search_slugs" in str(e):
43
43
  raise CommandError(
44
44
  "Missing manager method 'update_search_slugs'. "
45
- "See model {}. Got {}".format(
46
- model._meta.label_lower, str(e)
47
- )
45
+ "See model {}. Got {}".format(model._meta.label_lower, str(e))
48
46
  )
49
47
  else:
50
48
  raise CommandError(e)
@@ -1,12 +1,12 @@
1
1
  # Generated by Django 3.2.13 on 2022-08-25 01:51
2
2
 
3
3
  import _socket
4
- from django.db import migrations, models
5
4
  import django_audit_fields.fields.hostname_modification_field
6
5
  import django_audit_fields.fields.userfield
7
6
  import django_audit_fields.fields.uuid_auto_field
8
7
  import django_audit_fields.models.audit_model_mixin
9
8
  import django_revision.revision_field
9
+ from django.db import migrations, models
10
10
 
11
11
 
12
12
  class Migration(migrations.Migration):
@@ -1,8 +1,8 @@
1
1
  # Generated by Django 4.2.4 on 2023-08-23 01:13
2
2
 
3
3
  import _socket
4
- from django.db import migrations, models
5
4
  import django_audit_fields.fields.hostname_modification_field
5
+ from django.db import migrations, models
6
6
 
7
7
 
8
8
  class Migration(migrations.Migration):
@@ -14,16 +14,12 @@ class Migration(migrations.Migration):
14
14
  migrations.AlterField(
15
15
  model_name="edcpermissions",
16
16
  name="device_created",
17
- field=models.CharField(
18
- blank=True, max_length=10, verbose_name="Device created"
19
- ),
17
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device created"),
20
18
  ),
21
19
  migrations.AlterField(
22
20
  model_name="edcpermissions",
23
21
  name="device_modified",
24
- field=models.CharField(
25
- blank=True, max_length=10, verbose_name="Device modified"
26
- ),
22
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device modified"),
27
23
  ),
28
24
  migrations.AlterField(
29
25
  model_name="edcpermissions",
@@ -82,9 +82,7 @@ def index_link(context):
82
82
  @register.filter
83
83
  @stringfilter
84
84
  def human(value):
85
- return "-".join(
86
- [value[i * 4 : (i + 1) * 4] for i in range(0, ceil(len(value) / 4))]
87
- )
85
+ return "-".join([value[i * 4 : (i + 1) * 4] for i in range(0, ceil(len(value) / 4))])
88
86
 
89
87
 
90
88
  @register.inclusion_tag(
@@ -110,9 +108,7 @@ def paginator_row(context):
110
108
 
111
109
  paginator_url_kwargs = context.get("paginator_url_kwargs") or {}
112
110
  if context.get("subject_identifier"):
113
- paginator_url_kwargs.update(
114
- subject_identifier=context.get("subject_identifier")
115
- )
111
+ paginator_url_kwargs.update(subject_identifier=context.get("subject_identifier"))
116
112
  paginator_url = reverse(paginator_url, kwargs=paginator_url_kwargs)
117
113
 
118
114
  if querystring:
@@ -105,9 +105,7 @@ class AdministrationViewMixin(ContextMixin):
105
105
  edc_keys.sort()
106
106
 
107
107
  other_sections = {
108
- k: v
109
- for k, v in sections.items()
110
- if not k.startswith(self.edc_module_prefix)
108
+ k: v for k, v in sections.items() if not k.startswith(self.edc_module_prefix)
111
109
  }
112
110
  other_keys = list(other_sections.keys())
113
111
  other_keys.sort()
@@ -35,9 +35,7 @@ class EdcViewMixin(
35
35
  kwargs.update(
36
36
  {
37
37
  "device_id": getattr(edc_device_app_config, "device_id", "device_id?"),
38
- "device_role": getattr(
39
- edc_device_app_config, "device_role", "device_role?"
40
- ),
38
+ "device_role": getattr(edc_device_app_config, "device_role", "device_role?"),
41
39
  "live_system": live_system,
42
40
  }
43
41
  )
@@ -5,8 +5,6 @@ from edc_navbar import NavbarViewMixin
5
5
  from ..view_mixins import AdministrationViewMixin, EdcViewMixin
6
6
 
7
7
 
8
- class AdministrationView(
9
- EdcViewMixin, NavbarViewMixin, AdministrationViewMixin, TemplateView
10
- ):
8
+ class AdministrationView(EdcViewMixin, NavbarViewMixin, AdministrationViewMixin, TemplateView):
11
9
  navbar_selected_item = "administration"
12
10
  navbar_name = "default" # settings.APP_NAME