clinicedc 2.0.1__py3-none-any.whl → 2.0.2__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.2.dist-info}/METADATA +15 -22
  2. {clinicedc-2.0.1.dist-info → clinicedc-2.0.2.dist-info}/RECORD +854 -787
  3. {clinicedc-2.0.1.dist-info → clinicedc-2.0.2.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.2.dist-info}/licenses/LICENSE +0 -0
@@ -121,9 +121,7 @@ class StockTransferAdmin(ModelAdminMixin, SimpleHistoryAdmin):
121
121
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stocktransferitem_changelist")
122
122
  url = f"{url}?q={obj.id}"
123
123
  context = dict(url=url, label=count, title="Go to stock transfer items")
124
- return render_to_string(
125
- "edc_pharmacy/stock/items_as_link.html", context=context
126
- )
124
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
127
125
 
128
126
  @admin.display(description="Confirmed at site")
129
127
  def stock_transfer_item_confirmed_changelist(self, obj):
@@ -137,9 +135,7 @@ class StockTransferAdmin(ModelAdminMixin, SimpleHistoryAdmin):
137
135
  label=num_confirmed_at_site,
138
136
  title="Items confirmed at site",
139
137
  )
140
- return render_to_string(
141
- "edc_pharmacy/stock/items_as_link.html", context=context
142
- )
138
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
143
139
 
144
140
  @admin.display(description="Unconfirmed")
145
141
  def stock_transfer_item_unconfirmed_changelist(self, obj):
@@ -156,15 +152,11 @@ class StockTransferAdmin(ModelAdminMixin, SimpleHistoryAdmin):
156
152
  label=num_transferred - num_confirmed_at_site,
157
153
  title="Items not confirmed at site",
158
154
  )
159
- return render_to_string(
160
- "edc_pharmacy/stock/items_as_link.html", context=context
161
- )
155
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
162
156
 
163
157
  @admin.display(description="Stock", ordering="stock__code")
164
158
  def stock_changelist(self, obj):
165
159
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
166
160
  url = f"{url}?q={obj.id}"
167
161
  context = dict(url=url, label="Stock", title="Go to stock")
168
- return render_to_string(
169
- "edc_pharmacy/stock/items_as_link.html", context=context
170
- )
162
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
@@ -120,9 +120,7 @@ class StockTransferItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
120
120
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
121
121
  url = f"{url}?q={obj.stock.code}"
122
122
  context = dict(url=url, label=obj.stock.code, title="Go to stock")
123
- return render_to_string(
124
- "edc_pharmacy/stock/items_as_link.html", context=context
125
- )
123
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
126
124
 
127
125
  @admin.display(
128
126
  description="Allocation",
@@ -133,13 +131,9 @@ class StockTransferItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
133
131
  url = reverse("edc_pharmacy_admin:edc_pharmacy_allocation_changelist")
134
132
  url = f"{url}?q={subject_identifier}"
135
133
  context = dict(url=url, label=subject_identifier, title="Go to allocation")
136
- return render_to_string(
137
- "edc_pharmacy/stock/items_as_link.html", context=context
138
- )
134
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
139
135
 
140
- @admin.display(
141
- description="Transfer #", ordering="stock_transfer__transfer_identifier"
142
- )
136
+ @admin.display(description="Transfer #", ordering="stock_transfer__transfer_identifier")
143
137
  def stock_transfer_changelist(self, obj):
144
138
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stocktransfer_changelist")
145
139
  url = f"{url}?q={obj.stock_transfer.id}"
@@ -148,9 +142,7 @@ class StockTransferItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
148
142
  label=obj.stock_transfer.transfer_identifier,
149
143
  title="Go to stock transfer",
150
144
  )
151
- return render_to_string(
152
- "edc_pharmacy/stock/items_as_link.html", context=context
153
- )
145
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
154
146
 
155
147
  @admin.display(
156
148
  description="Site Confirmation #",
@@ -167,15 +159,11 @@ class StockTransferItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
167
159
  title="Go to stock transfer site confirmation",
168
160
  )
169
161
  else:
170
- url = reverse(
171
- "edc_pharmacy_admin:edc_pharmacy_confirmationatsiteitem_changelist"
172
- )
162
+ url = reverse("edc_pharmacy_admin:edc_pharmacy_confirmationatsiteitem_changelist")
173
163
  url = f"{url}?q={transfer_confirmation_item.pk}"
174
164
  context = dict(
175
165
  url=url,
176
166
  label=transfer_confirmation_item.transfer_confirmation_item_identifier,
177
167
  title="Go to stock transfer confirmation item",
178
168
  )
179
- return render_to_string(
180
- "edc_pharmacy/stock/items_as_link.html", context=context
181
- )
169
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
@@ -90,9 +90,7 @@ class StorageBinAdmin(SiteModelAdminMixin, ModelAdminMixin, SimpleHistoryAdmin):
90
90
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
91
91
  url = f"{url}?q={obj.id}"
92
92
  context = dict(url=url, label="Stock", title="Go to stock")
93
- return render_to_string(
94
- "edc_pharmacy/stock/items_as_link.html", context=context
95
- )
93
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
96
94
 
97
95
  @admin.display(description="Items")
98
96
  def storage_bin_item_changelist(self, obj):
@@ -100,13 +98,7 @@ class StorageBinAdmin(SiteModelAdminMixin, ModelAdminMixin, SimpleHistoryAdmin):
100
98
  url = reverse("edc_pharmacy_admin:edc_pharmacy_storagebinitem_changelist")
101
99
  url = f"{url}?q={obj.id}"
102
100
  context = dict(url=url, label=f"Items ({items})", title="Go to bin items")
103
- return render_to_string(
104
- "edc_pharmacy/stock/items_as_link.html", context=context
105
- )
101
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
106
102
 
107
103
  def get_view_only_site_ids_for_user(self, request) -> list[int]:
108
- return [
109
- s.id
110
- for s in request.user.userprofile.sites.all()
111
- if s.id != request.site.id
112
- ]
104
+ return [s.id for s in request.user.userprofile.sites.all() if s.id != request.site.id]
@@ -26,9 +26,7 @@ class StorageBinItemAdmin(SiteModelAdminMixin, ModelAdminMixin, SimpleHistoryAdm
26
26
  autocomplete_fields = ["stock"]
27
27
  actions = ["delete_selected"]
28
28
 
29
- change_list_note = (
30
- "Once an item is dispensed it is automatically removed from storage."
31
- )
29
+ change_list_note = "Once an item is dispensed it is automatically removed from storage."
32
30
 
33
31
  form = StorageBinItemForm
34
32
 
@@ -88,18 +86,14 @@ class StorageBinItemAdmin(SiteModelAdminMixin, ModelAdminMixin, SimpleHistoryAdm
88
86
  url = reverse("edc_pharmacy_admin:edc_pharmacy_storagebin_changelist")
89
87
  url = f"{url}?q={bin_ref}"
90
88
  context = dict(url=url, label=bin_ref, title="Go to bin")
91
- return render_to_string(
92
- "edc_pharmacy/stock/items_as_link.html", context=context
93
- )
89
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
94
90
 
95
91
  @admin.display(description="Stock")
96
92
  def stock_changelist(self, obj):
97
93
  url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
98
94
  url = f"{url}?q={obj.stock.code}"
99
95
  context = dict(url=url, label=obj.stock.code, title="Go to stock")
100
- return render_to_string(
101
- "edc_pharmacy/stock/items_as_link.html", context=context
102
- )
96
+ return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
103
97
 
104
98
  @admin.display(
105
99
  description="Subject #",
@@ -113,8 +107,4 @@ class StorageBinItemAdmin(SiteModelAdminMixin, ModelAdminMixin, SimpleHistoryAdm
113
107
  return qs.filter(stock__dispenseitem__isnull=True)
114
108
 
115
109
  def get_view_only_site_ids_for_user(self, request) -> list[int]:
116
- return [
117
- s.id
118
- for s in request.user.userprofile.sites.all()
119
- if s.id != request.site.id
120
- ]
110
+ return [s.id for s in request.user.userprofile.sites.all() if s.id != request.site.id]
@@ -50,16 +50,12 @@ def get_next_scheduled_visit_for_subjects_df(
50
50
  if stock_request.cutoff_datetime:
51
51
  df_appt = df_appt[
52
52
  df_appt.next_appt_datetime
53
- <= pd.Timestamp(
54
- stock_request.cutoff_datetime.date()
55
- ).to_datetime64()
53
+ <= pd.Timestamp(stock_request.cutoff_datetime.date()).to_datetime64()
56
54
  ]
57
55
  df_appt = df_appt.reset_index(drop=True)
58
56
  # get the first appointment due
59
57
  df = (
60
- df_appt[
61
- (df_appt.appt_status == NEW_APPT) & (df_appt.visit_code_sequence == 0)
62
- ]
58
+ df_appt[(df_appt.appt_status == NEW_APPT) & (df_appt.visit_code_sequence == 0)]
63
59
  .sort_values(by=["appt_datetime"])
64
60
  .groupby(by=["subject_identifier"])
65
61
  .first()
@@ -70,9 +66,7 @@ def get_next_scheduled_visit_for_subjects_df(
70
66
 
71
67
  # merge with registered_subject
72
68
  df_registered_subject = read_frame(
73
- get_registered_subject_model_cls().objects.values(
74
- "id", "subject_identifier"
75
- ),
69
+ get_registered_subject_model_cls().objects.values("id", "subject_identifier"),
76
70
  verbose=False,
77
71
  )
78
72
  df_registered_subject = df_registered_subject.rename(
@@ -26,9 +26,7 @@ def in_stock_for_subjects_df(
26
26
  stock_cls = django_apps.get_model("edc_pharmacy.stock")
27
27
 
28
28
  # qs of stock in stock and allocated to a subject_identifier
29
- difference = ExpressionWrapper(
30
- F("qty_in") - F("qty_out"), output_field=DecimalField()
31
- )
29
+ difference = ExpressionWrapper(F("qty_in") - F("qty_out"), output_field=DecimalField())
32
30
  qs = (
33
31
  stock_cls.objects.filter(
34
32
  allocation__isnull=False,
@@ -66,9 +64,7 @@ def in_stock_for_subjects_df(
66
64
  df_sites = read_frame(Site.objects.all(), verbose=False)
67
65
  df_sites = df_sites.rename(columns={"id": "site_id"})
68
66
  df_location = read_frame(location_cls.objects.all(), verbose=False)
69
- df_location = df_location.merge(
70
- df_sites[["name", "site_id"]], on="name", how="left"
71
- )
67
+ df_location = df_location.merge(df_sites[["name", "site_id"]], on="name", how="left")
72
68
  df_location = df_location.rename(columns={"id": "location"})
73
69
  df = df.merge(df_location[["location", "site_id"]], how="left", on="location")
74
70
 
@@ -45,9 +45,7 @@ def stock_for_subjects_df() -> pd.DataFrame:
45
45
  ).filter(confirmationatsiteitem__isnull=False, dispenseitem__isnull=True),
46
46
  verbose=False,
47
47
  ).rename(
48
- columns={
49
- "allocation__registered_subject__subject_identifier": "subject_identifier"
50
- }
48
+ columns={"allocation__registered_subject__subject_identifier": "subject_identifier"}
51
49
  )
52
50
 
53
51
  df = pd.merge(
@@ -26,15 +26,12 @@ class StudyMedicationFormValidator(CrfFormValidator):
26
26
  self.confirm_has_rx()
27
27
 
28
28
  if self.related_visit.appointment.relative_next:
29
- next_appt_datetime = (
30
- self.related_visit.appointment.relative_next.appt_datetime
31
- )
29
+ next_appt_datetime = self.related_visit.appointment.relative_next.appt_datetime
32
30
 
33
31
  if next_appt_datetime:
34
32
  if (
35
33
  self.refill_start_datetime
36
- and self.refill_start_datetime.astimezone(ZoneInfo("UTC"))
37
- > next_appt_datetime
34
+ and self.refill_start_datetime.astimezone(ZoneInfo("UTC")) > next_appt_datetime
38
35
  ):
39
36
  local_dte = formatted_datetime(next_appt_datetime)
40
37
  error_msg = (
@@ -55,14 +52,9 @@ class StudyMedicationFormValidator(CrfFormValidator):
55
52
  inverse=False,
56
53
  )
57
54
 
58
- if (
59
- not self.next_appointment
60
- and self.cleaned_data.get("refill_to_next_visit") == YES
61
- ):
55
+ if not self.next_appointment and self.cleaned_data.get("refill_to_next_visit") == YES:
62
56
  error_msg = "Invalid. Subject does not have a future appointment."
63
- self.raise_validation_error(
64
- {"refill_to_next_visit": error_msg}, INVALID_ERROR
65
- )
57
+ self.raise_validation_error({"refill_to_next_visit": error_msg}, INVALID_ERROR)
66
58
 
67
59
  self.validate_refill_dates()
68
60
 
@@ -138,9 +130,7 @@ class StudyMedicationFormValidator(CrfFormValidator):
138
130
  "Invalid. Cannot be after offschedule datetime. "
139
131
  f"Got {self.offschedule_datetime}."
140
132
  )
141
- self.raise_validation_error(
142
- {"refill_start_datetime": error_msg}, INVALID_ERROR
143
- )
133
+ self.raise_validation_error({"refill_start_datetime": error_msg}, INVALID_ERROR)
144
134
 
145
135
  def validate_refill_end_date_against_offschedule_date(self):
146
136
  if (
@@ -152,9 +142,7 @@ class StudyMedicationFormValidator(CrfFormValidator):
152
142
  "Invalid. Cannot be after offschedule datetime. "
153
143
  f"Got {self.offschedule_datetime}."
154
144
  )
155
- self.raise_validation_error(
156
- {"refill_end_datetime": error_msg}, INVALID_ERROR
157
- )
145
+ self.raise_validation_error({"refill_end_datetime": error_msg}, INVALID_ERROR)
158
146
 
159
147
  def validate_refill_dates(self):
160
148
  if (
@@ -167,13 +155,9 @@ class StudyMedicationFormValidator(CrfFormValidator):
167
155
  "and time must exactly match refill start date and time."
168
156
  )
169
157
  if not self.refill_end_datetime:
170
- self.raise_validation_error(
171
- {"refill_end_datetime": error_msg}, INVALID_ERROR
172
- )
158
+ self.raise_validation_error({"refill_end_datetime": error_msg}, INVALID_ERROR)
173
159
  elif self.refill_start_datetime != self.refill_end_datetime:
174
- self.raise_validation_error(
175
- {"refill_end_datetime": error_msg}, INVALID_ERROR
176
- )
160
+ self.raise_validation_error({"refill_end_datetime": error_msg}, INVALID_ERROR)
177
161
 
178
162
  if (
179
163
  self.cleaned_data.get("refill")
@@ -193,6 +177,4 @@ class StudyMedicationFormValidator(CrfFormValidator):
193
177
  "Invalid. Refill end date must be after the refill start date and "
194
178
  "before the next visit"
195
179
  )
196
- self.raise_validation_error(
197
- {"refill_end_datetime": error_msg}, INVALID_ERROR
198
- )
180
+ self.raise_validation_error({"refill_end_datetime": error_msg}, INVALID_ERROR)
@@ -7,15 +7,11 @@ class ContainerForm(forms.ModelForm):
7
7
 
8
8
  def clean(self):
9
9
  cleaned_data = super().clean()
10
- if cleaned_data.get("max_per_subject") and not cleaned_data.get(
11
- "may_request_as"
12
- ):
10
+ if cleaned_data.get("max_per_subject") and not cleaned_data.get("may_request_as"):
13
11
  raise forms.ValidationError(
14
12
  {"max_per_subject": "Not applicable. Leave blank or 0"}
15
13
  )
16
- if not cleaned_data.get("max_per_subject") and cleaned_data.get(
17
- "may_request_as"
18
- ):
14
+ if not cleaned_data.get("max_per_subject") and cleaned_data.get("may_request_as"):
19
15
  raise forms.ValidationError({"max_per_subject": "This field is required"})
20
16
  if (
21
17
  cleaned_data.get("max_per_subject")
@@ -23,16 +23,12 @@ class ReceiveItemForm(forms.ModelForm):
23
23
  cleaned_data.get("order_item").product.assignment
24
24
  != cleaned_data.get("lot").assignment
25
25
  ):
26
- raise forms.ValidationError(
27
- {"lot": "Lot assignment does not match product"}
28
- )
26
+ raise forms.ValidationError({"lot": "Lot assignment does not match product"})
29
27
 
30
28
  # in unit_qty's
31
29
  if cleaned_data.get("qty"):
32
30
  # TODO: clean this up
33
- qty_ordered = self.order_item.unit_qty + (
34
- self.order_item.unit_qty_received or 0
35
- )
31
+ qty_ordered = self.order_item.unit_qty + (self.order_item.unit_qty_received or 0)
36
32
  qty_already_received = self._meta.model.objects.filter(
37
33
  order_item=self.order_item
38
34
  ).aggregate(unit_qty=Sum("unit_qty"))["unit_qty"] or Decimal(0)
@@ -20,8 +20,7 @@ class RepackRequestForm(forms.ModelForm):
20
20
  )
21
21
  if (
22
22
  cleaned_data.get("container")
23
- and cleaned_data.get("container")
24
- == cleaned_data.get("from_stock").container
23
+ and cleaned_data.get("container") == cleaned_data.get("from_stock").container
25
24
  ):
26
25
  raise forms.ValidationError(
27
26
  {"container": "Stock is already packed in this container."}
@@ -31,23 +30,17 @@ class RepackRequestForm(forms.ModelForm):
31
30
  and cleaned_data.get("container").qty
32
31
  > cleaned_data.get("from_stock").container.qty
33
32
  ):
34
- raise forms.ValidationError(
35
- {"container": "Cannot pack into larger container."}
36
- )
33
+ raise forms.ValidationError({"container": "Cannot pack into larger container."})
37
34
  if cleaned_data.get("requested_qty") and self.instance.processed_qty:
38
35
  if cleaned_data.get("requested_qty") < self.instance.processed_qty:
39
36
  raise forms.ValidationError(
40
- {
41
- "requested_qty": "Cannot be less than the number of containers processed"
42
- }
37
+ {"requested_qty": "Cannot be less than the number of containers processed"}
43
38
  )
44
39
  if (
45
40
  cleaned_data.get("requested_qty") * cleaned_data.get("container").qty
46
41
  > cleaned_data.get("from_stock").unit_qty
47
42
  ):
48
- needed_qty = (
49
- cleaned_data.get("requested_qty") * cleaned_data.get("container").qty
50
- )
43
+ needed_qty = cleaned_data.get("requested_qty") * cleaned_data.get("container").qty
51
44
  on_hand_qty = cleaned_data.get("from_stock").unit_qty
52
45
  raise forms.ValidationError(
53
46
  {
@@ -30,16 +30,10 @@ class StockRequestForm(forms.ModelForm):
30
30
  raise forms.ValidationError(
31
31
  {"subject_identifiers": "Not all subject identifiers are valid."}
32
32
  )
33
- if cleaned_data.get("excluded_subject_identifiers") and cleaned_data.get(
34
- "location"
35
- ):
36
- subject_identifiers = cleaned_data.get(
37
- "excluded_subject_identifiers"
38
- ).split("\n")
33
+ if cleaned_data.get("excluded_subject_identifiers") and cleaned_data.get("location"):
34
+ subject_identifiers = cleaned_data.get("excluded_subject_identifiers").split("\n")
39
35
  subject_identifiers = [s.strip() for s in subject_identifiers]
40
- self.cleaned_data["excluded_subject_identifiers"] = "\n".join(
41
- subject_identifiers
42
- )
36
+ self.cleaned_data["excluded_subject_identifiers"] = "\n".join(subject_identifiers)
43
37
  if RegisteredSubject.objects.values("subject_identifier").filter(
44
38
  subject_identifier__in=subject_identifiers,
45
39
  site_id=cleaned_data.get("location").site_id,
@@ -84,8 +78,7 @@ class StockRequestForm(forms.ModelForm):
84
78
  if (
85
79
  cleaned_data.get("request_datetime")
86
80
  and cleaned_data.get("cutoff_datetime")
87
- and cleaned_data.get("cutoff_datetime")
88
- < cleaned_data.get("request_datetime")
81
+ and cleaned_data.get("cutoff_datetime") < cleaned_data.get("request_datetime")
89
82
  ):
90
83
  raise forms.ValidationError(
91
84
  {"cutoff_datetime": "Invalid. Must after the request date"}
@@ -97,9 +90,7 @@ class StockRequestForm(forms.ModelForm):
97
90
  == cleaned_data.get("request_datetime").date()
98
91
  ):
99
92
  raise forms.ValidationError(
100
- {
101
- "cutoff_datetime": "Invalid. Must be at least 1 day after the request date"
102
- }
93
+ {"cutoff_datetime": "Invalid. Must be at least 1 day after the request date"}
103
94
  )
104
95
  if (
105
96
  cleaned_data.get("start_datetime")
@@ -17,9 +17,7 @@ class StockRequestItemForm(forms.ModelForm):
17
17
  randomization_datetime__isnull=False,
18
18
  )
19
19
  except ObjectDoesNotExist:
20
- raise forms.ValidationError(
21
- {"subject_identifier": "Subject does not exist"}
22
- )
20
+ raise forms.ValidationError({"subject_identifier": "Subject does not exist"})
23
21
  return cleaned_data
24
22
 
25
23
  class Meta:
@@ -44,9 +44,7 @@ def draw_bulk_stock_label_code128(
44
44
  fontSize=10,
45
45
  )
46
46
  )
47
- label.add(
48
- String(15, height - 66, f"Expires: {obj.lot.expiration_date}", fontSize=10)
49
- )
47
+ label.add(String(15, height - 66, f"Expires: {obj.lot.expiration_date}", fontSize=10))
50
48
 
51
49
  formulation = obj.product.formulation
52
50
  text = (
@@ -23,18 +23,12 @@ def draw_bulk_stock_label_code39(
23
23
  br.x = width - 100
24
24
  br.y = height - 40
25
25
  label.add(br)
26
- label.add(
27
- String(15, height - 20, ResearchProtocolConfig().protocol_name, fontSize=10)
28
- )
26
+ label.add(String(15, height - 20, ResearchProtocolConfig().protocol_name, fontSize=10))
29
27
  qty = format_qty(obj.container.qty, obj.container)
30
28
 
31
29
  label.add(String(15, height - 40, f"{qty} tabs", fontSize=10))
32
30
  label.add(String(15, height - 60, f"Lot: {obj.lot.lot_no}", fontSize=10))
33
- label.add(
34
- String(15, height - 80, f"Expires: {obj.lot.expiration_date}", fontSize=10)
35
- )
36
- product = obj.product.formulation.get_description_with_assignment(
37
- obj.product.assignment
38
- )
31
+ label.add(String(15, height - 80, f"Expires: {obj.lot.expiration_date}", fontSize=10))
32
+ product = obj.product.formulation.get_description_with_assignment(obj.product.assignment)
39
33
  label.add(String(15, height - 100, f"{product}", fontSize=10))
40
34
  return label
@@ -38,9 +38,7 @@ def draw_patient_stock_label_code128(
38
38
  f"{formulation.medication} {int(formulation.strength)}"
39
39
  f"{formulation.get_units_display()} "
40
40
  )
41
- label.add(
42
- String(15, height - 72, ResearchProtocolConfig().protocol_name, fontSize=10)
43
- )
41
+ label.add(String(15, height - 72, ResearchProtocolConfig().protocol_name, fontSize=10))
44
42
  label.add(String(15, height - 84, f"{product}", fontSize=10))
45
43
  label.add(String(15, height - 96, f"{qty} tabs", fontSize=10))
46
44
  return label
@@ -10,15 +10,15 @@ import django_audit_fields.fields.userfield
10
10
  import django_audit_fields.fields.uuid_auto_field
11
11
  import django_audit_fields.models.audit_model_mixin
12
12
  import django_revision.revision_field
13
- import edc_registration.models.managers
14
- import edc_sites.models
15
- import edc_utils.date
16
13
  import simple_history.models
17
14
  from django.conf import settings
18
15
  from django.db import migrations, models
19
16
 
20
17
  import edc_pharmacy.models.medication
21
18
  import edc_pharmacy.models.prescription
19
+ import edc_registration.models.managers
20
+ import edc_sites.models
21
+ import edc_utils.date
22
22
 
23
23
 
24
24
  class Migration(migrations.Migration):
@@ -1918,9 +1918,7 @@ class Migration(migrations.Migration):
1918
1918
  ),
1919
1919
  (
1920
1920
  "weight_in_kgs",
1921
- models.DecimalField(
1922
- blank=True, decimal_places=1, max_digits=6, null=True
1923
- ),
1921
+ models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True),
1924
1922
  ),
1925
1923
  ("clinician_initials", models.CharField(max_length=3, null=True)),
1926
1924
  (
@@ -2071,9 +2069,7 @@ class Migration(migrations.Migration):
2071
2069
  ),
2072
2070
  (
2073
2071
  "weight_in_kgs",
2074
- models.DecimalField(
2075
- blank=True, decimal_places=1, max_digits=6, null=True
2076
- ),
2072
+ models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True),
2077
2073
  ),
2078
2074
  (
2079
2075
  "refill_date",
@@ -3171,9 +3167,7 @@ class Migration(migrations.Migration):
3171
3167
  ),
3172
3168
  (
3173
3169
  "weight_in_kgs",
3174
- models.DecimalField(
3175
- blank=True, decimal_places=1, max_digits=6, null=True
3176
- ),
3170
+ models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True),
3177
3171
  ),
3178
3172
  ("clinician_initials", models.CharField(max_length=3, null=True)),
3179
3173
  (
@@ -3328,9 +3322,7 @@ class Migration(migrations.Migration):
3328
3322
  ),
3329
3323
  (
3330
3324
  "weight_in_kgs",
3331
- models.DecimalField(
3332
- blank=True, decimal_places=1, max_digits=6, null=True
3333
- ),
3325
+ models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True),
3334
3326
  ),
3335
3327
  (
3336
3328
  "refill_date",
@@ -1,8 +1,9 @@
1
1
  # Generated by Django 3.2.11 on 2022-04-15 14:47
2
2
 
3
+ from django.db import migrations
4
+
3
5
  import edc_action_item.models.action_model_mixin
4
6
  import edc_sites.models
5
- from django.db import migrations
6
7
 
7
8
 
8
9
  class Migration(migrations.Migration):
@@ -10,11 +10,12 @@ import django_audit_fields.fields.uuid_auto_field
10
10
  import django_audit_fields.models.audit_model_mixin
11
11
  import django_crypto_fields.fields.encrypted_char_field
12
12
  import django_revision.revision_field
13
- import edc_utils.date
14
13
  import simple_history.models
15
14
  from django.conf import settings
16
15
  from django.db import migrations, models
17
16
 
17
+ import edc_utils.date
18
+
18
19
 
19
20
  class Migration(migrations.Migration):
20
21
  dependencies = [
@@ -140,9 +141,7 @@ class Migration(migrations.Migration):
140
141
  ),
141
142
  (
142
143
  "plural_name",
143
- models.CharField(
144
- max_length=250, null=True, verbose_name="Plural name"
145
- ),
144
+ models.CharField(max_length=250, null=True, verbose_name="Plural name"),
146
145
  ),
147
146
  (
148
147
  "display_name",
@@ -1061,9 +1060,7 @@ class Migration(migrations.Migration):
1061
1060
  ),
1062
1061
  (
1063
1062
  "plural_name",
1064
- models.CharField(
1065
- max_length=250, null=True, verbose_name="Plural name"
1066
- ),
1063
+ models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1067
1064
  ),
1068
1065
  (
1069
1066
  "display_name",
@@ -1129,23 +1126,17 @@ class Migration(migrations.Migration):
1129
1126
  migrations.AddField(
1130
1127
  model_name="container",
1131
1128
  name="plural_name",
1132
- field=models.CharField(
1133
- max_length=250, null=True, verbose_name="Plural name"
1134
- ),
1129
+ field=models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1135
1130
  ),
1136
1131
  migrations.AddField(
1137
1132
  model_name="formulationtype",
1138
1133
  name="plural_name",
1139
- field=models.CharField(
1140
- max_length=250, null=True, verbose_name="Plural name"
1141
- ),
1134
+ field=models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1142
1135
  ),
1143
1136
  migrations.AddField(
1144
1137
  model_name="frequencyunits",
1145
1138
  name="plural_name",
1146
- field=models.CharField(
1147
- max_length=250, null=True, verbose_name="Plural name"
1148
- ),
1139
+ field=models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1149
1140
  ),
1150
1141
  migrations.AddField(
1151
1142
  model_name="historicalmedicationlot",
@@ -1170,16 +1161,12 @@ class Migration(migrations.Migration):
1170
1161
  migrations.AddField(
1171
1162
  model_name="route",
1172
1163
  name="plural_name",
1173
- field=models.CharField(
1174
- max_length=250, null=True, verbose_name="Plural name"
1175
- ),
1164
+ field=models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1176
1165
  ),
1177
1166
  migrations.AddField(
1178
1167
  model_name="units",
1179
1168
  name="plural_name",
1180
- field=models.CharField(
1181
- max_length=250, null=True, verbose_name="Plural name"
1182
- ),
1169
+ field=models.CharField(max_length=250, null=True, verbose_name="Plural name"),
1183
1170
  ),
1184
1171
  migrations.AddIndex(
1185
1172
  model_name="unittype",
@@ -1,8 +1,9 @@
1
1
  # Generated by Django 3.2.13 on 2022-09-29 14:42
2
2
 
3
- import edc_sites.models
4
3
  from django.db import migrations, models
5
4
 
5
+ import edc_sites.models
6
+
6
7
 
7
8
  class Migration(migrations.Migration):
8
9
  dependencies = [