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
@@ -58,7 +58,5 @@ class SimpleDeathReportModelMixin(
58
58
  verbose_name = "Death Report"
59
59
  verbose_name_plural = "Death Reports"
60
60
  indexes = ActionModelMixin.Meta.indexes + [
61
- models.Index(
62
- fields=["subject_identifier", "action_identifier", "site", "id"]
63
- )
61
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])
64
62
  ]
@@ -107,9 +107,7 @@ class AeTmgModelAdminMixin(
107
107
  initial = super().get_changeform_initial_data(request)
108
108
  ae_initial_model_cls = get_ae_model("aeinitial")
109
109
  try:
110
- ae_initial = ae_initial_model_cls.objects.get(
111
- pk=request.GET.get("ae_initial")
112
- )
110
+ ae_initial = ae_initial_model_cls.objects.get(pk=request.GET.get("ae_initial"))
113
111
  except ObjectDoesNotExist:
114
112
  pass
115
113
  else:
@@ -104,9 +104,7 @@ class DeathReportModelAdminMixin(
104
104
  if cause_of_death == OTHER:
105
105
  cause_of_death = f"Other: {obj.cause_of_death_other}"
106
106
  else:
107
- cause_of_death = getattr(
108
- obj.cause_of_death, "display_name", obj.cause_of_death
109
- )
107
+ cause_of_death = getattr(obj.cause_of_death, "display_name", obj.cause_of_death)
110
108
  return cause_of_death
111
109
 
112
110
  @display(description="Report date", ordering="report_datetime")
@@ -127,15 +125,11 @@ class DeathReportModelAdminMixin(
127
125
  def action_item_column(self, obj):
128
126
  return self.get_action_item_column(obj.action_item, as_button=False)
129
127
 
130
- @display(
131
- description="Parent action", ordering="parent_action_item__action_identifier"
132
- )
128
+ @display(description="Parent action", ordering="parent_action_item__action_identifier")
133
129
  def parent_action_item_column(self, obj):
134
130
  return self.get_action_item_column(obj.parent_action_item, as_button=True)
135
131
 
136
- @display(
137
- description="Related action", ordering="related_action_item__action_identifier"
138
- )
132
+ @display(description="Related action", ordering="related_action_item__action_identifier")
139
133
  def related_action_item_column(self, obj):
140
134
  return self.get_action_item_column(obj.related_action_item, as_button=True)
141
135
 
@@ -145,7 +139,9 @@ class DeathReportModelAdminMixin(
145
139
  verbose_name = action_item.reference_model_cls._meta.verbose_name
146
140
  app_label = action_item.reference_model_cls._meta.app_label
147
141
  model_name = action_item.reference_model_cls._meta.model_name
148
- url_name = f"{get_adverse_event_app_label()}_admin:{app_label}_{model_name}_changelist"
142
+ url_name = (
143
+ f"{get_adverse_event_app_label()}_admin:{app_label}_{model_name}_changelist"
144
+ )
149
145
  url = reverse(url_name)
150
146
  return render_to_string(
151
147
  "edc_adverse_event/action_item_column.html",
@@ -23,9 +23,7 @@ class AeTmgModelFormMixin(AeModelFormMixin):
23
23
  widgets = {
24
24
  "subject_identifier": forms.TextInput(attrs={"readonly": "readonly"}),
25
25
  "action_identifier": forms.TextInput(attrs={"readonly": "readonly"}),
26
- "ae_description": forms.Textarea(
27
- attrs={"readonly": "readonly", "cols": "79"}
28
- ),
26
+ "ae_description": forms.Textarea(attrs={"readonly": "readonly", "cols": "79"}),
29
27
  "ae_classification": forms.TextInput(attrs={"readonly": "readonly"}),
30
28
  "ae_classification_other": forms.TextInput(attrs={"readonly": "readonly"}),
31
29
  }
@@ -49,9 +49,7 @@ def update_ae_initial_for_susar(sender, instance, raw, update_fields, **kwargs):
49
49
  if instance.ae_initial.susar_reported != YES:
50
50
  instance.ae_initial.susar = YES
51
51
  instance.ae_initial.susar_reported = YES
52
- instance.ae_initial.save(
53
- update_fields=["susar", "susar_reported"]
54
- )
52
+ instance.ae_initial.save(update_fields=["susar", "susar_reported"])
55
53
  elif instance.ae_initial.susar_reported != NO:
56
54
  instance.ae_initial.susar = YES
57
55
  instance.ae_initial.susar_reported = NO
@@ -100,9 +98,7 @@ def post_delete_ae_susar(instance, **kwargs):
100
98
  instance.ae_initial.save()
101
99
 
102
100
 
103
- @receiver(
104
- m2m_changed, weak=False, dispatch_uid="update_death_notifications_for_tmg_group"
105
- )
101
+ @receiver(m2m_changed, weak=False, dispatch_uid="update_death_notifications_for_tmg_group")
106
102
  def update_death_notifications_for_tmg_group(
107
103
  action, instance, reverse, model, pk_set, using, **kwargs
108
104
  ):
@@ -112,9 +108,7 @@ def update_death_notifications_for_tmg_group(
112
108
  pass
113
109
  else:
114
110
  try:
115
- tmg_death_notification = Notification.objects.get(
116
- name=DEATH_REPORT_TMG_ACTION
117
- )
111
+ tmg_death_notification = Notification.objects.get(name=DEATH_REPORT_TMG_ACTION)
118
112
  except ObjectDoesNotExist:
119
113
  pass
120
114
  else:
@@ -89,9 +89,7 @@ class AePdfReport(CrfPdfReport):
89
89
  susar_reported = ""
90
90
  if self.model_obj.susar == YES:
91
91
  susar_reported = (
92
- ": reported"
93
- if self.model_obj.susar_reported == YES
94
- else ": not reported"
92
+ ": reported" if self.model_obj.susar_reported == YES else ": not reported"
95
93
  )
96
94
  susar_text = f"{self.model_obj.get_susar_display()}{susar_reported}"
97
95
 
@@ -176,9 +174,7 @@ class AePdfReport(CrfPdfReport):
176
174
  t1 = Table([["Section 2: Follow-up Reports"]], (18 * cm))
177
175
  self.set_table_style(t1, bg_cmd=self.bg_cmd)
178
176
  total = self.model_obj.ae_follow_ups.count()
179
- row_text = (
180
- f"There {p.plural_verb('is', total)} {p.no('follow-up report', total)}."
181
- )
177
+ row_text = f"There {p.plural_verb('is', total)} {p.no('follow-up report', total)}."
182
178
  t2 = Table([[row_text]], (18 * cm))
183
179
  self.set_table_style(t2)
184
180
  story.append(KeepTogether([t1, t2]))
@@ -203,9 +199,7 @@ class AePdfReport(CrfPdfReport):
203
199
  ],
204
200
  (3 * cm, 3 * cm, 3 * cm, 9 * cm),
205
201
  )
206
- self.set_table_style(
207
- t, bg_cmd=("BACKGROUND", (0, 0), (3, -1), colors.lightgrey)
208
- )
202
+ self.set_table_style(t, bg_cmd=("BACKGROUND", (0, 0), (3, -1), colors.lightgrey))
209
203
  story.append(t)
210
204
 
211
205
  followups = self.model_obj.ae_follow_ups.order_by("-created")
@@ -213,9 +207,7 @@ class AePdfReport(CrfPdfReport):
213
207
  for followup in followups:
214
208
  qs = followup.history.filter(id=followup.id).order_by("-history_date")
215
209
  for obj in qs:
216
- username = (
217
- obj.user_created if obj.history_type == "+" else obj.user_modified
218
- )
210
+ username = obj.user_created if obj.history_type == "+" else obj.user_modified
219
211
  t = Table(
220
212
  [
221
213
  [
@@ -225,9 +217,7 @@ class AePdfReport(CrfPdfReport):
225
217
  ),
226
218
  Paragraph(username, s),
227
219
  Paragraph(obj.modified.strftime("%Y-%m-%d %H:%M"), s),
228
- Paragraph(
229
- fill(self.history_change_message(obj), width=60), s
230
- ),
220
+ Paragraph(fill(self.history_change_message(obj), width=60), s),
231
221
  ]
232
222
  ],
233
223
  (3 * cm, 3 * cm, 3 * cm, 9 * cm),
@@ -241,9 +231,7 @@ class AePdfReport(CrfPdfReport):
241
231
  .order_by("-history_date")
242
232
  )
243
233
  for obj in qs:
244
- username = (
245
- obj.user_created if obj.history_type == "+" else obj.user_modified
246
- )
234
+ username = obj.user_created if obj.history_type == "+" else obj.user_modified
247
235
  t = Table(
248
236
  [
249
237
  [
@@ -127,9 +127,7 @@ class DeathPdfReport(CrfPdfReport):
127
127
  ],
128
128
  (3 * cm, 3 * cm, 3 * cm, 9 * cm),
129
129
  )
130
- self.set_table_style(
131
- t, bg_cmd=("BACKGROUND", (0, 0), (3, -1), colors.lightgrey)
132
- )
130
+ self.set_table_style(t, bg_cmd=("BACKGROUND", (0, 0), (3, -1), colors.lightgrey))
133
131
  story.append(t)
134
132
 
135
133
  qs = (
@@ -138,9 +136,7 @@ class DeathPdfReport(CrfPdfReport):
138
136
  .order_by("-history_date")
139
137
  )
140
138
  for obj in qs:
141
- username = (
142
- obj.user_created if obj.history_type == "+" else obj.user_modified
143
- )
139
+ username = obj.user_created if obj.history_type == "+" else obj.user_modified
144
140
  t = Table(
145
141
  [
146
142
  [
@@ -157,9 +153,7 @@ class DeathPdfReport(CrfPdfReport):
157
153
 
158
154
  @property
159
155
  def cause_of_death(self):
160
- return getattr(
161
- self.model_obj.cause_of_death, "name", self.model_obj.cause_of_death
162
- )
156
+ return getattr(self.model_obj.cause_of_death, "name", self.model_obj.cause_of_death)
163
157
 
164
158
  @property
165
159
  def cause_of_death_other(self):
@@ -44,9 +44,7 @@ if TYPE_CHECKING:
44
44
 
45
45
  class DeathReportTmgModel(DeathReportTmgModelMixin, BaseUuidModel): ... # noqa
46
46
 
47
- class DeathReportTmgSecondModel(
48
- DeathReportTmgModelMixin, BaseUuidModel
49
- ): ... # noqa
47
+ class DeathReportTmgSecondModel(DeathReportTmgModelMixin, BaseUuidModel): ... # noqa
50
48
 
51
49
  class AeInitialModel(AeInitialModelMixin, BaseUuidModel): ... # noqa
52
50
 
@@ -119,9 +117,7 @@ def format_ae_followup_description(context, ae_followup, wrap_length):
119
117
  context["sae_reason"] = format_html(
120
118
  "{}",
121
119
  mark_safe(
122
- wrapx(
123
- escape_braces(ae_followup.ae_initial.sae_reason.name), wrap_length
124
- )
120
+ wrapx(escape_braces(ae_followup.ae_initial.sae_reason.name), wrap_length)
125
121
  ), # nosec B703, B308
126
122
  )
127
123
  except AttributeError:
@@ -198,9 +194,7 @@ def ae_tmg_queryset(subject_identifier: str = None) -> QuerySet[DeathReportTmgMo
198
194
  def death_report_tmg_queryset(
199
195
  subject_identifier: str = None,
200
196
  ) -> QuerySet[DeathReportTmgModel]:
201
- return get_ae_model("deathreporttmg").objects.filter(
202
- subject_identifier=subject_identifier
203
- )
197
+ return get_ae_model("deathreporttmg").objects.filter(subject_identifier=subject_identifier)
204
198
 
205
199
 
206
200
  @register.simple_tag
@@ -216,9 +210,7 @@ def death_report_tmg2_queryset(
216
210
  def death_report_queryset(
217
211
  subject_identifier: str = None,
218
212
  ) -> QuerySet[DeathReportTmgSecondModel]:
219
- return get_ae_model("deathreport").objects.filter(
220
- subject_identifier=subject_identifier
221
- )
213
+ return get_ae_model("deathreport").objects.filter(subject_identifier=subject_identifier)
222
214
 
223
215
 
224
216
  @register.simple_tag
@@ -306,9 +298,7 @@ def render_tmg_panel(
306
298
  else:
307
299
  panel_color = "success"
308
300
  # panel_label
309
- display_name = action_item.display_name.replace("Submit", "").replace(
310
- "pending", ""
311
- )
301
+ display_name = action_item.display_name.replace("Submit", "").replace("pending", "")
312
302
  identifier = action_item.identifier or "New"
313
303
  panel_label = _(f"{display_name} {identifier}")
314
304
  return dict(
@@ -39,9 +39,7 @@ def validate_ae_initial_outcome_date(form_obj):
39
39
  convert_php_dateformat(settings.SHORT_DATE_FORMAT)
40
40
  )
41
41
  raise forms.ValidationError(
42
- {
43
- "outcome_date": f"May not be before the AE start date {formatted_dte}."
44
- }
42
+ {"outcome_date": f"May not be before the AE start date {formatted_dte}."}
45
43
  )
46
44
 
47
45
 
@@ -73,9 +71,7 @@ def get_hospitalization_model_app_label() -> str:
73
71
 
74
72
  def get_ae_model(
75
73
  model_name,
76
- ) -> (
77
- Type[DeathReportModelMixin] | Type[AeInitialModelMixin] | Type[AeFollowupModelMixin]
78
- ):
74
+ ) -> Type[DeathReportModelMixin] | Type[AeInitialModelMixin] | Type[AeFollowupModelMixin]:
79
75
  return django_apps.get_model(f"{get_adverse_event_app_label()}.{model_name}")
80
76
 
81
77
 
@@ -87,9 +87,7 @@ class AeListboardViewMixin(
87
87
  return super().get_context_data(**kwargs)
88
88
 
89
89
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
90
- q_object, options = super().get_queryset_filter_options(
91
- request, *args, **kwargs
92
- )
90
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
93
91
  options.update(
94
92
  action_type__name__in=self.action_type_names,
95
93
  status__in=[NEW, OPEN, CLOSED],
@@ -80,9 +80,7 @@ class DeathReportListboardViewMixin(
80
80
  return super().get_context_data(**kwargs)
81
81
 
82
82
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
83
- q_object, options = super().get_queryset_filter_options(
84
- request, *args, **kwargs
85
- )
83
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
86
84
  options.update(
87
85
  action_type__name__in=self.action_type_names,
88
86
  status__in=[NEW, OPEN, CLOSED],
@@ -87,9 +87,7 @@ class TmgAeListboardViewMixin(
87
87
  ]
88
88
 
89
89
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
90
- q_object, options = super().get_queryset_filter_options(
91
- request, *args, **kwargs
92
- )
90
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
93
91
  options.update(
94
92
  action_type__name__in=self.action_type_names,
95
93
  status__in=[NEW, OPEN, CLOSED],
@@ -108,8 +106,6 @@ class StatusTmgAeListboardView(TmgAeListboardViewMixin):
108
106
  return super().get_context_data(**kwargs)
109
107
 
110
108
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
111
- q_object, options = super().get_queryset_filter_options(
112
- request, *args, **kwargs
113
- )
109
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
114
110
  options.update({"status": self.status})
115
111
  return q_object, options
@@ -28,9 +28,7 @@ if TYPE_CHECKING:
28
28
 
29
29
  @dataclass
30
30
  class TmgButton(ModelButton):
31
- model_obj: (
32
- DeathReportTmgModel | DeathReportModel | AeFollowupModel | AeInitialModel
33
- ) = None
31
+ model_obj: DeathReportTmgModel | DeathReportModel | AeFollowupModel | AeInitialModel = None
34
32
  next_url_name: str | None = field(default="open_tmg_ae_listboard_url")
35
33
  only_user_created_may_access: bool | None = None
36
34
  forloop_counter: int | None = None
@@ -73,9 +71,7 @@ class TmgButton(ModelButton):
73
71
  and self.only_user_created_may_access
74
72
  and self.model_obj.user_created != self.user.username
75
73
  ):
76
- title = _("May only be edited by %(user)s") % {
77
- "user": self.model_obj.user_created
78
- }
74
+ title = _("May only be edited by %(user)s") % {"user": self.model_obj.user_created}
79
75
  if self.model_obj.site.id != self.request.site.id:
80
76
  title = _("%(title)s when logged into site %(site)s") % {
81
77
  "title": title,
@@ -37,8 +37,6 @@ class AeHomeView(UrlRequestContextMixin, EdcViewMixin, NavbarViewMixin, Template
37
37
  ae_initial_changelist_url=ae_initial_changelist_url,
38
38
  death_report_changelist_url=death_report_changelist_url,
39
39
  death_report_listboard_url=death_report_listboard_url,
40
- **self.add_url_to_context(
41
- new_key="ae_home_url", existing_key=self.url_name
42
- ),
40
+ **self.add_url_to_context(new_key="ae_home_url", existing_key=self.url_name),
43
41
  )
44
42
  return super().get_context_data(**kwargs)
@@ -50,9 +50,7 @@ class DeathListboardView(
50
50
  return super().get_context_data(**kwargs)
51
51
 
52
52
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
53
- q_object, options = super().get_queryset_filter_options(
54
- request, *args, **kwargs
55
- )
53
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
56
54
  if self.search_term and re.match("^[A-Z]+$", self.search_term):
57
55
  q_object |= Q(first_name__exact=self.search_term)
58
56
  if kwargs.get("subject_identifier"):
@@ -33,18 +33,14 @@ class TmgHomeView(EdcViewMixin, NavbarViewMixin, TemplateView):
33
33
  )
34
34
  # summarize new and open for notice
35
35
  qs = (
36
- ActionItem.objects.filter(
37
- action_type__name=AE_TMG_ACTION, status__in=[NEW, OPEN]
38
- )
36
+ ActionItem.objects.filter(action_type__name=AE_TMG_ACTION, status__in=[NEW, OPEN])
39
37
  .exclude(site__name=get_current_site(request=self.request).name)
40
38
  .values("status", "site__name")
41
39
  .annotate(items=Count("status"))
42
40
  )
43
41
  notices = []
44
42
  for item in qs.order_by("status", "site__name"):
45
- notices.append(
46
- [item.get("site__name"), item.get("status"), item.get("items")]
47
- )
43
+ notices.append([item.get("site__name"), item.get("status"), item.get("items")])
48
44
  new_count = ActionItem.objects.filter(
49
45
  action_type__name=AE_TMG_ACTION,
50
46
  site__name=get_current_site(request=self.request).name,
@@ -61,8 +61,6 @@ class SummaryListboardView(
61
61
  return super().get_context_data(**kwargs)
62
62
 
63
63
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
64
- q_object, options = super().get_queryset_filter_options(
65
- request, *args, **kwargs
66
- )
64
+ q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
67
65
  options.update({"action_type__name__in": self.action_type_names})
68
66
  return q_object, options
@@ -304,8 +304,6 @@ class AppointmentAdmin(
304
304
  def get_view_only_site_ids_for_user(self, request) -> list[int]:
305
305
  if request.user.userprofile.roles.filter(name=DATA_MANAGER_ROLE).exists():
306
306
  return [
307
- s.id
308
- for s in request.user.userprofile.sites.all()
309
- if s.id != request.site.id
307
+ s.id for s in request.user.userprofile.sites.all() if s.id != request.site.id
310
308
  ]
311
309
  return super().get_view_only_site_ids_for_user(request)
@@ -35,9 +35,7 @@ class AppointmentStatusListFilter(SimpleListFilter):
35
35
  field_name = "appt_status"
36
36
 
37
37
  def lookups(self, request, model_admin) -> tuple:
38
- return APPT_STATUS + (
39
- (ATTENDED_APPT, "Attended (In progress, incomplete, done)"),
40
- )
38
+ return APPT_STATUS + ((ATTENDED_APPT, "Attended (In progress, incomplete, done)"),)
41
39
 
42
40
  def queryset(self, request, queryset):
43
41
  qs = None
@@ -2,6 +2,4 @@ from edc_model_admin.admin_site import EdcAdminSite
2
2
 
3
3
  from .apps import AppConfig
4
4
 
5
- edc_appointment_admin = EdcAdminSite(
6
- name="edc_appointment_admin", app_label=AppConfig.name
7
- )
5
+ edc_appointment_admin = EdcAdminSite(name="edc_appointment_admin", app_label=AppConfig.name)
@@ -17,9 +17,7 @@ def get_appointment_df(
17
17
  normalize = True if normalize is None else normalize
18
18
  localize = True if localize is None else localize
19
19
  appointment_model_cls = get_appointment_model_cls()
20
- appointment_type_model_cls = django_apps.get_model(
21
- "edc_appointment.appointmenttype"
22
- )
20
+ appointment_type_model_cls = django_apps.get_model("edc_appointment.appointmenttype")
23
21
  opts = {}
24
22
  if site_id:
25
23
  opts = {"site_id": site_id}
@@ -28,9 +26,7 @@ def get_appointment_df(
28
26
  appointment_model_cls.objects.values(*values).filter(**opts), verbose=False
29
27
  )
30
28
  else:
31
- df_appt = read_frame(
32
- appointment_model_cls.objects.filter(**opts), verbose=False
33
- )
29
+ df_appt = read_frame(appointment_model_cls.objects.filter(**opts), verbose=False)
34
30
  df_appt = convert_dates_from_model(
35
31
  df_appt, appointment_model_cls, normalize=normalize, localize=localize
36
32
  )
@@ -173,8 +173,7 @@ class AppointmentReasonUpdater(MetadataHelperMixin):
173
173
  """
174
174
  return (
175
175
  self.get_crf_metadata_by(KEYED).count() == 1
176
- and self.get_crf_metadata_by(KEYED)[0].model
177
- == get_subject_visit_missed_model()
176
+ and self.get_crf_metadata_by(KEYED)[0].model == get_subject_visit_missed_model()
178
177
  )
179
178
 
180
179
  def delete_subject_visit_missed_if_exists(self) -> None:
@@ -187,9 +186,7 @@ class AppointmentReasonUpdater(MetadataHelperMixin):
187
186
  """Returns a subject visit reason given the appt reason"""
188
187
  if appt_reason == SCHEDULED_APPT:
189
188
  visit_reason = SCHEDULED
190
- elif (
191
- appt_reason == UNSCHEDULED_APPT and self.appointment.visit_code_sequence > 0
192
- ):
189
+ elif appt_reason == UNSCHEDULED_APPT and self.appointment.visit_code_sequence > 0:
193
190
  visit_reason = UNSCHEDULED
194
191
  else:
195
192
  raise AppointmentReasonUpdaterError(
@@ -30,10 +30,7 @@ class AppointmentStatusUpdater:
30
30
  raise AppointmentStatusUpdaterError(
31
31
  "Appointment instance must exist. Got `id` is None"
32
32
  )
33
- if (
34
- change_to_in_progress
35
- and self.appointment.appt_status != IN_PROGRESS_APPT
36
- ):
33
+ if change_to_in_progress and self.appointment.appt_status != IN_PROGRESS_APPT:
37
34
  self.appointment.appt_status = IN_PROGRESS_APPT
38
35
  self.appointment.save_base(update_fields=["appt_status"])
39
36
  if clear_others_in_progress:
@@ -19,9 +19,7 @@ INVALID_PREVIOUS_APPOINTMENT_NOT_UPDATED = "previous_appointment_not_updated"
19
19
  INVALID_PREVIOUS_VISIT_MISSING = "previous_visit_missing"
20
20
  INVALID_MISSED_APPT_NOT_ALLOWED = "invalid_missed_appt_not_allowed"
21
21
  INVALID_APPT_STATUS_AT_BASELINE = "invalid_appt_status_at_baseline"
22
- INVALID_SKIPPED_APPT_NOT_ALLOWED_AT_BASELINE = (
23
- "invalid_skipped_appt_not_allowed_at_baseline"
24
- )
22
+ INVALID_SKIPPED_APPT_NOT_ALLOWED_AT_BASELINE = "invalid_skipped_appt_not_allowed_at_baseline"
25
23
  INVALID_APPT_TIMING = "invalid_appt_timing"
26
24
  INVALID_APPT_TIMING_CRFS_EXIST = "invalid_appt_timing_crfs_exist"
27
25
  INVALID_APPT_TIMING_REQUISITIONS_EXIST = "invalid_appt_timing_requisitions_exist"
@@ -86,8 +86,7 @@ class AppointmentCreator:
86
86
  try:
87
87
  if is_naive(timepoint_datetime):
88
88
  raise ValueError(
89
- f"Naive datetime not allowed. {repr(self)}. "
90
- f"Got {timepoint_datetime}"
89
+ f"Naive datetime not allowed. {repr(self)}. " f"Got {timepoint_datetime}"
91
90
  )
92
91
  else:
93
92
  self.timepoint_datetime = timepoint_datetime
@@ -100,16 +99,13 @@ class AppointmentCreator:
100
99
  # to timepoint_datetime still apply.
101
100
  if suggested_datetime and is_naive(suggested_datetime):
102
101
  raise ValueError(
103
- f"Naive datetime not allowed. {repr(self)}. "
104
- f"Got {suggested_datetime}"
102
+ f"Naive datetime not allowed. {repr(self)}. " f"Got {suggested_datetime}"
105
103
  )
106
104
  else:
107
105
  self.suggested_datetime = suggested_datetime or self.timepoint_datetime
108
106
  self.facility = facility or visit.facility
109
107
  if not self.facility:
110
- raise AppointmentCreatorError(
111
- f"facility_name not defined. See {repr(visit)}"
112
- )
108
+ raise AppointmentCreatorError(f"facility_name not defined. See {repr(visit)}")
113
109
  self.get_appointment()
114
110
 
115
111
  def __repr__(self):
@@ -129,9 +125,7 @@ class AppointmentCreator:
129
125
  """Returns a newly created or updated appointment model instance."""
130
126
  if not self._appointment:
131
127
  try:
132
- self._appointment = self.appointment_model_cls.objects.get(
133
- **self.options
134
- )
128
+ self._appointment = self.appointment_model_cls.objects.get(**self.options)
135
129
  except ObjectDoesNotExist:
136
130
  self._appointment = self._create()
137
131
  else:
@@ -77,9 +77,7 @@ class UnscheduledAppointmentCreator:
77
77
  "suggested visit code sequence cannot be less than 1"
78
78
  )
79
79
  self.facility = facility
80
- self.visit_schedule = site_visit_schedules.get_visit_schedule(
81
- visit_schedule_name
82
- )
80
+ self.visit_schedule = site_visit_schedules.get_visit_schedule(visit_schedule_name)
83
81
  self.schedule = self.visit_schedule.schedules.get(schedule_name)
84
82
  self.appointment_model_cls = self.schedule.appointment_model_cls
85
83
  self.visit = self.visit_schedule.schedules.get(self.schedule_name).visits.get(
@@ -264,10 +262,8 @@ class UnscheduledAppointmentCreator:
264
262
  if (
265
263
  self.calling_appointment
266
264
  and self.calling_appointment.next
267
- and self.calling_appointment.next.appt_status
268
- in [INCOMPLETE_APPT, COMPLETE_APPT]
269
- and self.suggested_appt_datetime
270
- < self.calling_appointment.next.appt_datetime
265
+ and self.calling_appointment.next.appt_status in [INCOMPLETE_APPT, COMPLETE_APPT]
266
+ and self.suggested_appt_datetime < self.calling_appointment.next.appt_datetime
271
267
  ):
272
268
  value = True
273
269
  return value
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from datetime import datetime
4
4
  from typing import TYPE_CHECKING
5
5
 
6
+ from dateutil.relativedelta import relativedelta
6
7
  from django.db import transaction
7
8
 
8
9
  from ..constants import INCOMPLETE_APPT, NEW_APPT
@@ -31,6 +32,9 @@ def create_unscheduled_appointment(
31
32
 
32
33
  """
33
34
  unscheduled_appointment = None
35
+ next_appt_datetime = next_appt_datetime or appointment.appt_datetime + relativedelta(
36
+ days=1
37
+ )
34
38
  next_appointment = get_appointment_by_datetime(
35
39
  next_appt_datetime,
36
40
  appointment.subject_identifier,
@@ -48,9 +48,7 @@ class NextAppointmentCrfFormValidatorMixin(FormValidator):
48
48
  field_required="health_facility",
49
49
  )
50
50
 
51
- if self.cleaned_data.get("appt_date") and self.cleaned_data.get(
52
- "visitschedule"
53
- ):
51
+ if self.cleaned_data.get("appt_date") and self.cleaned_data.get("visitschedule"):
54
52
  self.validate_with_appointment_form_validator()
55
53
  self.validate_date_is_on_clinic_day()
56
54
 
@@ -105,9 +103,7 @@ class NextAppointmentCrfFormValidatorMixin(FormValidator):
105
103
  and instance.appt_datetime.date() != self.cleaned_data.get("appt_date")
106
104
  ):
107
105
  self.raise_validation_error(
108
- {
109
- "appt_date": "May not be changed. Next appointment has already started"
110
- },
106
+ {"appt_date": "May not be changed. Next appointment has already started"},
111
107
  INVALID_ERROR,
112
108
  )
113
109
 
@@ -159,10 +155,7 @@ class NextAppointmentCrfFormValidatorMixin(FormValidator):
159
155
  def health_facility(self) -> HealthFacility | None:
160
156
  if not self._health_facility:
161
157
  if self.cleaned_data.get("health_facility"):
162
- if (
163
- self.cleaned_data.get("health_facility").site
164
- != self.related_visit.site
165
- ):
158
+ if self.cleaned_data.get("health_facility").site != self.related_visit.site:
166
159
  raise self.raise_validation_error(
167
160
  {"health_facility": "Invalid for this site"}, INVALID_ERROR
168
161
  )