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
edc_navbar/navbar.py CHANGED
@@ -20,9 +20,7 @@ class Navbar:
20
20
 
21
21
  def register(self, navbar_item: NavbarItem):
22
22
  if navbar_item in self.navbar_items:
23
- raise NavbarError(
24
- f"Duplicate navbar item. See {self}. Got{navbar_item.name}"
25
- )
23
+ raise NavbarError(f"Duplicate navbar item. See {self}. Got{navbar_item.name}")
26
24
  self.navbar_items.append(navbar_item)
27
25
 
28
26
  @property
edc_navbar/navbar_item.py CHANGED
@@ -52,9 +52,7 @@ class NavbarItem:
52
52
  try:
53
53
  url_name = url_names.get(self.url_name)
54
54
  except InvalidDashboardUrlName:
55
- url_name = (
56
- self.url_name.split(":")[1] if self.no_url_namespace else self.url_name
57
- )
55
+ url_name = self.url_name.split(":")[1] if self.no_url_namespace else self.url_name
58
56
  return url_name
59
57
 
60
58
  def set_disabled(self, user: User | None = None):
@@ -34,9 +34,7 @@ class NavbarCollection:
34
34
  self.registry.update({navbar.name: navbar})
35
35
  # self.codenames.update(**navbar.codenames)
36
36
  else:
37
- raise AlreadyRegistered(
38
- f"Navbar with name {navbar.name} is already registered."
39
- )
37
+ raise AlreadyRegistered(f"Navbar with name {navbar.name} is already registered.")
40
38
 
41
39
  def context(self, name=None, selected_item=None):
42
40
  """Returns the named navbar in the collection as context."""
@@ -92,9 +90,7 @@ class NavbarCollection:
92
90
  try:
93
91
  before_import_registry = copy.copy(site_navbars.registry)
94
92
  import_module(f"{app}.{module_name}")
95
- writer(
96
- f" - registered navbars '{module_name}' from '{app}'\n"
97
- )
93
+ writer(f" - registered navbars '{module_name}' from '{app}'\n")
98
94
  except NavbarError as e:
99
95
  writer(f" * loading {app}.navbars ... \n")
100
96
  writer(style.ERROR(f"ERROR! {e}\n"))
@@ -15,9 +15,7 @@ def render_navbar(context) -> dict:
15
15
  user = getattr(context["request"], "user", None)
16
16
  user_id = getattr(user, "id", None)
17
17
  try:
18
- auth_user_change_url = reverse(
19
- "edc_auth_admin:auth_user_change", args=(user_id,)
20
- )
18
+ auth_user_change_url = reverse("edc_auth_admin:auth_user_change", args=(user_id,))
21
19
  except NoReverseMatch:
22
20
  pass
23
21
  return dict(
@@ -2,6 +2,4 @@ from edc_model_admin.admin_site import EdcAdminSite
2
2
 
3
3
  from .apps import AppConfig
4
4
 
5
- edc_notification_admin = EdcAdminSite(
6
- name="edc_notification_admin", app_label=AppConfig.name
7
- )
5
+ edc_notification_admin = EdcAdminSite(name="edc_notification_admin", app_label=AppConfig.name)
@@ -81,9 +81,7 @@ class MailingListManager:
81
81
  a member to the list.
82
82
  """
83
83
  if not self.email_enabled:
84
- raise EmailNotEnabledError(
85
- "Email is not enabled. See settings.EMAIL_ENABLED"
86
- )
84
+ raise EmailNotEnabledError("Email is not enabled. See settings.EMAIL_ENABLED")
87
85
  if not user.email:
88
86
  raise UserEmailError(f"User {user}'s email address is not defined.")
89
87
  response = requests.post(
@@ -107,9 +105,7 @@ class MailingListManager:
107
105
  a member from the list.
108
106
  """
109
107
  if not self.email_enabled:
110
- raise EmailNotEnabledError(
111
- "Email is not enabled. See settings.EMAIL_ENABLED"
112
- )
108
+ raise EmailNotEnabledError("Email is not enabled. See settings.EMAIL_ENABLED")
113
109
  response = requests.put(
114
110
  f"{self.api_url}/{self.address}/members/{user.email}",
115
111
  auth=("api", self.api_key),
@@ -140,9 +136,7 @@ class MailingListManager:
140
136
  def create(self, verbose: bool | None = None) -> Response:
141
137
  """Returns a response after attempting to create the list."""
142
138
  if not self.email_enabled:
143
- raise EmailNotEnabledError(
144
- "Email is not enabled. See settings.EMAIL_ENABLED"
145
- )
139
+ raise EmailNotEnabledError("Email is not enabled. See settings.EMAIL_ENABLED")
146
140
  response = requests.post(
147
141
  self.api_url,
148
142
  auth=("api", self.api_key),
@@ -163,9 +157,7 @@ class MailingListManager:
163
157
  def delete(self) -> Response:
164
158
  """Returns a response after attempting to delete the list."""
165
159
  if not self.email_enabled:
166
- raise EmailNotEnabledError(
167
- "Email is not enabled. See settings.EMAIL_ENABLED"
168
- )
160
+ raise EmailNotEnabledError("Email is not enabled. See settings.EMAIL_ENABLED")
169
161
  return requests.delete(
170
162
  f"{self.api_url}/{self.address}", auth=("api", self.api_key), timeout=10
171
163
  )
@@ -175,9 +167,7 @@ class MailingListManager:
175
167
  a member from the list.
176
168
  """
177
169
  if not self.email_enabled:
178
- raise EmailNotEnabledError(
179
- "Email is not enabled. See settings.EMAIL_ENABLED"
180
- )
170
+ raise EmailNotEnabledError("Email is not enabled. See settings.EMAIL_ENABLED")
181
171
  return requests.delete(
182
172
  f"{self.api_url}/{self.address}/members/{user.email}",
183
173
  auth=("api", self.api_key),
@@ -3,10 +3,11 @@
3
3
  import _socket
4
4
  import django_audit_fields.fields.uuid_auto_field
5
5
  import django_revision.revision_field
6
+ from django.db import migrations, models
7
+
6
8
  import edc_model_fields.fields.hostname_modification_field
7
9
  import edc_model_fields.fields.userfield
8
10
  import edc_utils
9
- from django.db import migrations, models
10
11
 
11
12
 
12
13
  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="notification",
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="notification",
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="notification",
@@ -16,9 +16,7 @@ class NotificationModelAdminMixin:
16
16
  notifications = site_notifications.models.get(self.model._meta.label_lower)
17
17
  notification_instructions = None
18
18
  if notifications:
19
- notifications = [
20
- notification.display_name for notification in notifications
21
- ]
19
+ notifications = [notification.display_name for notification in notifications]
22
20
  tooltip1 = mark_safe(", ".join(notifications)) # nosec B308 B703
23
21
  my_notifications = [
24
22
  n.display_name
@@ -20,9 +20,7 @@ class Notification(BaseUuidModel):
20
20
 
21
21
  display_name = models.CharField(max_length=255, unique=True)
22
22
 
23
- mailing_list_address = models.EmailField(
24
- _("Mailing list address"), blank=True, null=True
25
- )
23
+ mailing_list_address = models.EmailField(_("Mailing list address"), blank=True, null=True)
26
24
 
27
25
  enabled = models.BooleanField(default=True)
28
26
 
@@ -20,10 +20,7 @@ def notification_on_post_create_historical_record(
20
20
 
21
21
  Note, this is the post_create of the historical model.
22
22
  """
23
- if (
24
- site_notifications.loaded
25
- and instance._meta.label_lower in site_notifications.models
26
- ):
23
+ if site_notifications.loaded and instance._meta.label_lower in site_notifications.models:
27
24
  opts = dict(
28
25
  instance=instance,
29
26
  user=instance.user_modified or instance.user_created,
@@ -36,12 +33,8 @@ def notification_on_post_create_historical_record(
36
33
  site_notifications.notify(**opts)
37
34
 
38
35
 
39
- @receiver(
40
- m2m_changed, weak=False, dispatch_uid="manage_mailists_on_userprofile_m2m_changed"
41
- )
42
- def manage_mailists_on_userprofile_m2m_changed(
43
- action, instance, pk_set, sender, **kwargs
44
- ):
36
+ @receiver(m2m_changed, weak=False, dispatch_uid="manage_mailists_on_userprofile_m2m_changed")
37
+ def manage_mailists_on_userprofile_m2m_changed(action, instance, pk_set, sender, **kwargs):
45
38
  """Updates the mail server mailing lists based on the
46
39
  selections in the UserProfile model.
47
40
  """
@@ -51,9 +51,7 @@ class ModelNotification(Notification):
51
51
  def __init__(self) -> None:
52
52
  super().__init__()
53
53
  if not self.display_name:
54
- self.display_name = django_apps.get_model(
55
- self.model
56
- )._meta.verbose_name.title()
54
+ self.display_name = django_apps.get_model(self.model)._meta.verbose_name.title()
57
55
 
58
56
  def __repr__(self) -> str:
59
57
  return (
@@ -65,9 +63,7 @@ class ModelNotification(Notification):
65
63
  def __str__(self) -> str:
66
64
  return f"{self.name}: {self.display_name} ({self.model})"
67
65
 
68
- def notify_on_condition(
69
- self, instance: BaseUuidHistoryModelStub = None, **kwargs
70
- ) -> bool:
66
+ def notify_on_condition(self, instance: BaseUuidHistoryModelStub = None, **kwargs) -> bool:
71
67
  """Returns True if the condition in one of the C(r)UD methods is met."""
72
68
  if instance._meta.label_lower == self.model:
73
69
  return (
@@ -136,9 +132,7 @@ class ModelNotification(Notification):
136
132
  changed_fields.update({field: values})
137
133
  return changed_fields or None
138
134
 
139
- def field_value_condition_on_update(
140
- self, field, previous_value, current_value
141
- ) -> bool:
135
+ def field_value_condition_on_update(self, field, previous_value, current_value) -> bool:
142
136
  """Returns True if the value has changed.
143
137
 
144
138
  Override for a more complex evaluation.
@@ -50,9 +50,7 @@ class Notification:
50
50
  "Thanks."
51
51
  )
52
52
  email_subject_template: str = (
53
- "{test_subject_line}{protocol_name}: "
54
- "{display_name} "
55
- "for {subject_identifier}"
53
+ "{test_subject_line}{protocol_name}: " "{display_name} " "for {subject_identifier}"
56
54
  )
57
55
  email_footer_template: str = (
58
56
  "\n\n-----------------\n"
@@ -124,14 +122,10 @@ class Notification:
124
122
  email_body_template = (
125
123
  email_body_template or self.email_body_template
126
124
  ) + self.email_footer_template
127
- email_sent = self.send_email(
128
- email_body_template=email_body_template, **kwargs
129
- )
125
+ email_sent = self.send_email(email_body_template=email_body_template, **kwargs)
130
126
  if use_sms:
131
127
  sms_sent = self.send_sms(**kwargs)
132
- self.post_notification_actions(
133
- email_sent=email_sent, sms_sent=sms_sent, **kwargs
134
- )
128
+ self.post_notification_actions(email_sent=email_sent, sms_sent=sms_sent, **kwargs)
135
129
  return True if email_sent or sms_sent else False
136
130
 
137
131
  def notify_on_condition(self, **kwargs) -> bool:
@@ -199,9 +193,7 @@ class Notification:
199
193
  instance=instance, test_message=test_message, **kwargs
200
194
  ),
201
195
  email_from=self.email_from,
202
- test_subject_line=(
203
- self.email_test_subject_line if test_message else ""
204
- ).strip(),
196
+ test_subject_line=(self.email_test_subject_line if test_message else "").strip(),
205
197
  test_body_line=self.email_test_body_line if test_message else "",
206
198
  test_line=self.sms_test_line if test_message else "",
207
199
  message_datetime=get_utcnow(),
@@ -60,9 +60,7 @@ class SiteNotifications:
60
60
  if not self.loaded:
61
61
  raise RegistryNotLoaded(self)
62
62
  if not self._registry.get(name):
63
- raise NotificationNotRegistered(
64
- f"Notification not registered. Got '{name}'."
65
- )
63
+ raise NotificationNotRegistered(f"Notification not registered. Got '{name}'.")
66
64
  return self._registry.get(name)
67
65
 
68
66
  def register(self, notification_cls: Type[Notification] = None):
@@ -80,9 +78,7 @@ class SiteNotifications:
80
78
  models = [getattr(notification_cls, "model")]
81
79
  for model in models:
82
80
  try:
83
- if notification_cls.name not in [
84
- n.name for n in self.models[model]
85
- ]:
81
+ if notification_cls.name not in [n.name for n in self.models[model]]:
86
82
  self.models[model].append(notification_cls)
87
83
  except KeyError:
88
84
  self.models.update({model: [notification_cls]})
@@ -126,9 +122,7 @@ class SiteNotifications:
126
122
  notification_model_cls.objects.all().update(enabled=False)
127
123
  if site_notifications.loaded:
128
124
  if verbose:
129
- sys.stdout.write(
130
- style.MIGRATE_HEADING("Populating Notification model:\n")
131
- )
125
+ sys.stdout.write(style.MIGRATE_HEADING("Populating Notification model:\n"))
132
126
  self.delete_unregistered_notifications(apps=apps)
133
127
  for name, notification_cls in site_notifications.registry.items():
134
128
  if verbose:
@@ -166,8 +160,7 @@ class SiteNotifications:
166
160
  if (
167
161
  get_email_enabled()
168
162
  and self.loaded
169
- and settings.EMAIL_BACKEND
170
- != "django.core.mail.backends.locmem.EmailBackend"
163
+ and settings.EMAIL_BACKEND != "django.core.mail.backends.locmem.EmailBackend"
171
164
  ):
172
165
  sys.stdout.write(style.MIGRATE_HEADING("Creating mailing lists:\n"))
173
166
  for name, notification_cls in self.registry.items():
@@ -181,9 +174,7 @@ class SiteNotifications:
181
174
  response = manager.create()
182
175
  except ConnectionError as e:
183
176
  sys.stdout.write(
184
- style.ERROR(
185
- f" * Failed to create mailing list {name}. " f"Got {e}\n"
186
- )
177
+ style.ERROR(f" * Failed to create mailing list {name}. " f"Got {e}\n")
187
178
  )
188
179
  else:
189
180
  if verbose:
@@ -3,13 +3,14 @@
3
3
  import _socket
4
4
  import django_audit_fields.fields.uuid_auto_field
5
5
  import django_revision.revision_field
6
+ from django.db import migrations, models
7
+
6
8
  import edc_model.validators.date
7
9
  import edc_model_fields.fields.hostname_modification_field
8
10
  import edc_model_fields.fields.other_charfield
9
11
  import edc_model_fields.fields.userfield
10
12
  import edc_protocol.validators
11
13
  import edc_utils
12
- from django.db import migrations, models
13
14
 
14
15
 
15
16
  class Migration(migrations.Migration):
@@ -4,6 +4,10 @@ import _socket
4
4
  import django.db.models.deletion
5
5
  import django_audit_fields.fields.uuid_auto_field
6
6
  import django_revision.revision_field
7
+ import simple_history.models
8
+ from django.conf import settings
9
+ from django.db import migrations, models
10
+
7
11
  import edc_model.validators.date
8
12
  import edc_model_fields.fields.hostname_modification_field
9
13
  import edc_model_fields.fields.other_charfield
@@ -11,9 +15,6 @@ import edc_model_fields.fields.userfield
11
15
  import edc_protocol.validators
12
16
  import edc_sites.models
13
17
  import edc_utils
14
- import simple_history.models
15
- from django.conf import settings
16
- from django.db import migrations, models
17
18
 
18
19
 
19
20
  class Migration(migrations.Migration):
@@ -1,8 +1,9 @@
1
1
  # Generated by Django 2.2.6 on 2019-11-01 21:33
2
2
 
3
- import edc_model_fields.fields.other_charfield
4
3
  from django.db import migrations
5
4
 
5
+ import edc_model_fields.fields.other_charfield
6
+
6
7
 
7
8
  class Migration(migrations.Migration):
8
9
  dependencies = [("edc_offstudy", "0007_auto_20191024_1000")]
@@ -1,7 +1,7 @@
1
1
  # Generated by Django 3.2.13 on 2022-09-24 21:32
2
2
 
3
- from django.db import migrations, models
4
3
  import django.db.models.deletion
4
+ from django.db import migrations, models
5
5
 
6
6
 
7
7
  class Migration(migrations.Migration):
@@ -1,6 +1,7 @@
1
1
  # Generated by Django 3.2.13 on 2022-09-29 14:42
2
2
 
3
3
  from django.db import migrations, models
4
+
4
5
  import edc_identifier.managers
5
6
  import edc_sites.models
6
7
 
@@ -1,8 +1,9 @@
1
1
  # Generated by Django 4.2.1 on 2023-07-07 19:32
2
2
 
3
+ from django.db import migrations
4
+
3
5
  import edc_identifier.managers
4
6
  import edc_sites.models
5
- from django.db import migrations
6
7
 
7
8
 
8
9
  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="historicalsubjectoffstudy",
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="historicalsubjectoffstudy",
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="historicalsubjectoffstudy",
@@ -49,16 +45,12 @@ class Migration(migrations.Migration):
49
45
  migrations.AlterField(
50
46
  model_name="subjectoffstudy",
51
47
  name="device_created",
52
- field=models.CharField(
53
- blank=True, max_length=10, verbose_name="Device created"
54
- ),
48
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device created"),
55
49
  ),
56
50
  migrations.AlterField(
57
51
  model_name="subjectoffstudy",
58
52
  name="device_modified",
59
- field=models.CharField(
60
- blank=True, max_length=10, verbose_name="Device modified"
61
- ),
53
+ field=models.CharField(blank=True, max_length=10, verbose_name="Device modified"),
62
54
  ),
63
55
  migrations.AlterField(
64
56
  model_name="subjectoffstudy",
@@ -60,9 +60,9 @@ class OffstudyModelMixin(UniqueSubjectIdentifierFieldMixin, models.Model):
60
60
  )
61
61
 
62
62
  def __str__(self):
63
- dte_str = self.report_datetime.astimezone(
64
- ZoneInfo(settings.TIME_ZONE)
65
- ).strftime(convert_php_dateformat(settings.SHORT_DATETIME_FORMAT))
63
+ dte_str = self.report_datetime.astimezone(ZoneInfo(settings.TIME_ZONE)).strftime(
64
+ convert_php_dateformat(settings.SHORT_DATETIME_FORMAT)
65
+ )
66
66
  return f"{self.subject_identifier} {dte_str}"
67
67
 
68
68
  def save(self, *args, **kwargs):
@@ -24,9 +24,7 @@ class OffstudyCrfModelFormMixin:
24
24
  the report_datetime.
25
25
  """
26
26
  if self.get_subject_identifier() and self.report_datetime:
27
- visit_schedule = site_visit_schedules.get_visit_schedule(
28
- self.visit_schedule_name
29
- )
27
+ visit_schedule = site_visit_schedules.get_visit_schedule(self.visit_schedule_name)
30
28
  schedule = visit_schedule.schedules.get(self.schedule_name)
31
29
  try:
32
30
  offschedule_obj = schedule.offschedule_model_cls.objects.get(
@@ -36,9 +34,7 @@ class OffstudyCrfModelFormMixin:
36
34
  except ObjectDoesNotExist:
37
35
  pass
38
36
  else:
39
- offschedule_datetime = formatted_datetime(
40
- offschedule_obj.offschedule_datetime
41
- )
37
+ offschedule_datetime = formatted_datetime(offschedule_obj.offschedule_datetime)
42
38
  raise forms.ValidationError(
43
39
  f"Subject was taken off schedule before this report datetime. "
44
40
  f"Got subject_identifier='{self.get_subject_identifier()}', "
@@ -8,9 +8,7 @@ register = template.Library()
8
8
 
9
9
 
10
10
  @register.inclusion_tag("edc_offstudy/visit_schedule_row.html")
11
- def offstudy_visit_schedule_row(
12
- subject_identifier, visit_schedule, subject_dashboard_url
13
- ):
11
+ def offstudy_visit_schedule_row(subject_identifier, visit_schedule, subject_dashboard_url):
14
12
  context = {}
15
13
  offstudy_model = visit_schedule.offstudy_model
16
14
  offstudy_model_cls = django_apps.get_model(offstudy_model)
@@ -21,9 +19,7 @@ def offstudy_visit_schedule_row(
21
19
  else:
22
20
  options = dict(subject_identifier=subject_identifier)
23
21
  query = unquote(urlencode(options))
24
- href = (
25
- f"{obj.get_absolute_url()}?next={subject_dashboard_url},subject_identifier"
26
- )
22
+ href = f"{obj.get_absolute_url()}?next={subject_dashboard_url},subject_identifier"
27
23
  href = "&".join([href, query])
28
24
  context = dict(
29
25
  offstudy_datetime=obj.offstudy_datetime,
edc_offstudy/utils.py CHANGED
@@ -48,9 +48,7 @@ def raise_if_offstudy(
48
48
  except ObjectDoesNotExist:
49
49
  pass
50
50
  else:
51
- msg_part = (
52
- f"Source model `{source_obj._meta.verbose_name}`." if source_obj else ""
53
- )
51
+ msg_part = f"Source model `{source_obj._meta.verbose_name}`." if source_obj else ""
54
52
  raise OffstudyError(
55
53
  "Subject off study by given date/time. "
56
54
  f"Got report_datetime=`{formatted_datetime(report_datetime)}` "
@@ -22,6 +22,4 @@ class PdfButtonModelAdminMixin:
22
22
  title=self.pdf_button_title,
23
23
  url_name=self.pdf_button_url_name,
24
24
  )
25
- return render_to_string(
26
- template_name=self.pdf_button_template_name, context=context
27
- )
25
+ return render_to_string(template_name=self.pdf_button_template_name, context=context)
@@ -97,9 +97,7 @@ class CrfPdfReport(Report):
97
97
  f"Got {self.model_obj}."
98
98
  )
99
99
  if not self.changelist_url:
100
- raise CrfPdfReportError(
101
- f"Invalid changelist url. Got {self.changelist_url}."
102
- )
100
+ raise CrfPdfReportError(f"Invalid changelist url. Got {self.changelist_url}.")
103
101
 
104
102
  self.user_model_cls = get_user_model()
105
103
  self.user = self.request.user if self.request else user
@@ -195,9 +193,7 @@ class CrfPdfReport(Report):
195
193
  ],
196
194
  [
197
195
  "Randomization date:",
198
- self.registered_subject.randomization_datetime.strftime(
199
- "%Y-%m-%d %H:%M"
200
- ),
196
+ self.registered_subject.randomization_datetime.strftime("%Y-%m-%d %H:%M"),
201
197
  ],
202
198
  ["Assignment:", assignment],
203
199
  ]
@@ -252,9 +248,7 @@ class CrfPdfReport(Report):
252
248
  @property
253
249
  def logo(self):
254
250
  if not self._logo:
255
- path = get_static_file(
256
- self.logo_data["app_label"], self.logo_data["filename"]
257
- )
251
+ path = get_static_file(self.logo_data["app_label"], self.logo_data["filename"])
258
252
  if os.path.isfile(path):
259
253
  self._logo = ImageReader(path)
260
254
  return self._logo
@@ -32,9 +32,7 @@ class TextboxFlowable(Flowable):
32
32
  y=y,
33
33
  width=width * 0.6,
34
34
  height=height * 0.4,
35
- borderStyle=(
36
- self.borderStyle if self.borderStyle != "underlined" else "none"
37
- ),
35
+ borderStyle=(self.borderStyle if self.borderStyle != "underlined" else "none"),
38
36
  fillColor=colors.white,
39
37
  textColor=colors.black,
40
38
  forceBorder=True,
edc_pdf_reports/report.py CHANGED
@@ -28,9 +28,7 @@ class ReportError(Exception):
28
28
 
29
29
  class Report(ABC):
30
30
  document_template = SimpleDocTemplate
31
- watermark_word: str | None = getattr(
32
- settings, "EDC_PDF_REPORTS_WATERMARK_WORD", None
33
- )
31
+ watermark_word: str | None = getattr(settings, "EDC_PDF_REPORTS_WATERMARK_WORD", None)
34
32
  watermark_font: tuple[str, int] | None = getattr(
35
33
  settings, "EDC_PDF_REPORTS_WATERMARK_FONT", ("Helvetica", 100)
36
34
  )
@@ -144,9 +142,7 @@ class Report(ABC):
144
142
  styles.add(ParagraphStyle(name="right", alignment=TA_RIGHT))
145
143
  styles.add(ParagraphStyle(name="left", alignment=TA_LEFT))
146
144
  styles.add(
147
- ParagraphStyle(
148
- name="line_data", alignment=TA_LEFT, fontSize=8, leading=10
149
- )
145
+ ParagraphStyle(name="line_data", alignment=TA_LEFT, fontSize=8, leading=10)
150
146
  )
151
147
  styles.add(
152
148
  ParagraphStyle(
@@ -186,24 +182,16 @@ class Report(ABC):
186
182
  )
187
183
  )
188
184
  styles.add(
189
- ParagraphStyle(
190
- name="line_label", fontSize=7, leading=6, alignment=TA_LEFT
191
- )
185
+ ParagraphStyle(name="line_label", fontSize=7, leading=6, alignment=TA_LEFT)
192
186
  )
193
187
  styles.add(
194
- ParagraphStyle(
195
- name="line_label_center", fontSize=7, alignment=TA_CENTER
196
- )
188
+ ParagraphStyle(name="line_label_center", fontSize=7, alignment=TA_CENTER)
197
189
  )
198
190
  styles.add(
199
- ParagraphStyle(
200
- name="row_header", fontSize=8, leading=8, alignment=TA_CENTER
201
- )
191
+ ParagraphStyle(name="row_header", fontSize=8, leading=8, alignment=TA_CENTER)
202
192
  )
203
193
  styles.add(
204
- ParagraphStyle(
205
- name="row_data", fontSize=7, leading=7, alignment=TA_CENTER
206
- )
194
+ ParagraphStyle(name="row_data", fontSize=7, leading=7, alignment=TA_CENTER)
207
195
  )
208
196
  self._styles = self.add_to_styles(styles)
209
197
  return self._styles