clinicedc 2.0.4__py3-none-any.whl → 2.0.6__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 (478) hide show
  1. {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/METADATA +41 -45
  2. {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/RECORD +478 -478
  3. edc_action_item/action.py +76 -54
  4. edc_action_item/action_item_notification.py +1 -3
  5. edc_action_item/action_with_notification.py +4 -4
  6. edc_action_item/create_action_item.py +2 -2
  7. edc_action_item/create_or_update_action_type.py +1 -1
  8. edc_action_item/data_fixers.py +4 -5
  9. edc_action_item/delete_action_item.py +0 -1
  10. edc_action_item/modeladmin_mixins.py +2 -4
  11. edc_action_item/modelform_mixins/modelform_mixins.py +1 -1
  12. edc_action_item/models/action_item.py +53 -38
  13. edc_action_item/models/action_model_mixin.py +17 -17
  14. edc_action_item/models/action_type.py +33 -13
  15. edc_action_item/models/reference.py +3 -2
  16. edc_action_item/site_action_items.py +13 -14
  17. edc_action_item/stubs.py +9 -9
  18. edc_action_item/templatetags/action_item_extras.py +2 -2
  19. edc_action_item/view_utils/action_item_button.py +3 -3
  20. edc_action_item/view_utils/action_item_popover_list_item.py +4 -4
  21. edc_adherence/form_validator_mixin.py +1 -1
  22. edc_adverse_event/action_items/ae_followup_action.py +1 -1
  23. edc_adverse_event/action_items/ae_initial_action.py +1 -1
  24. edc_adverse_event/action_items/ae_susar_action.py +1 -1
  25. edc_adverse_event/action_items/ae_tmg_action.py +1 -1
  26. edc_adverse_event/action_items/death_report_action.py +1 -2
  27. edc_adverse_event/action_items/death_report_tmg_action.py +1 -1
  28. edc_adverse_event/action_items/death_report_tmg_second_action.py +1 -1
  29. edc_adverse_event/action_items/hospitalization_action.py +1 -1
  30. edc_adverse_event/form_validator_mixins/death_report_form_validator.py +3 -3
  31. edc_adverse_event/form_validator_mixins/requires_death_report_form_validator_mixin.py +3 -4
  32. edc_adverse_event/form_validators/death_report_tmg.py +1 -1
  33. edc_adverse_event/model_mixins/ae_followup/ae_followup_methods_model_mixin.py +3 -3
  34. edc_adverse_event/model_mixins/ae_followup/ae_followup_model_mixin.py +3 -3
  35. edc_adverse_event/model_mixins/ae_initial/ae_initial_fields_model_mixin.py +0 -1
  36. edc_adverse_event/model_mixins/ae_initial/ae_initial_methods_model_mixin.py +3 -3
  37. edc_adverse_event/model_mixins/ae_initial/ae_initial_model_mixin.py +3 -3
  38. edc_adverse_event/model_mixins/ae_special_interest/aesi_methods_model_mixin.py +4 -4
  39. edc_adverse_event/model_mixins/ae_special_interest/aesi_model_mixin.py +3 -3
  40. edc_adverse_event/model_mixins/ae_susar/ae_susar_methods_model_mixin.py +4 -4
  41. edc_adverse_event/model_mixins/ae_susar/ae_susar_model_mixin.py +3 -3
  42. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_fields_model_mixin.py +4 -5
  43. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_methods_model_mixin.py +4 -4
  44. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_model_mixin.py +3 -3
  45. edc_adverse_event/model_mixins/death_report/death_report_extra_fields_model_mixin.py +2 -3
  46. edc_adverse_event/model_mixins/death_report/death_report_model_mixin.py +11 -11
  47. edc_adverse_event/model_mixins/death_report/death_report_tmg_model_mixin.py +9 -11
  48. edc_adverse_event/model_mixins/death_report/simple_death_report_model_mixin.py +7 -6
  49. edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +0 -1
  50. edc_adverse_event/modeladmin_mixins/ae_followup_admin_mixin.py +9 -11
  51. edc_adverse_event/modeladmin_mixins/ae_initial_admin_mixin.py +4 -6
  52. edc_adverse_event/modeladmin_mixins/modeladmin_mixins.py +1 -1
  53. edc_adverse_event/modeladmin_mixins/utils.py +4 -4
  54. edc_adverse_event/models/signals.py +7 -19
  55. edc_adverse_event/pdf_reports/death_pdf_report.py +8 -9
  56. edc_adverse_event/templatetags/edc_adverse_event_extras.py +10 -20
  57. edc_adverse_event/urls.py +7 -3
  58. edc_adverse_event/utils.py +2 -2
  59. edc_adverse_event/view_utils/tmg_button.py +4 -4
  60. edc_appconfig/system_checks.py +1 -1
  61. edc_appointment/appointment_status_updater.py +14 -15
  62. edc_appointment/creators/appointment_creator.py +7 -11
  63. edc_appointment/creators/appointments_creator.py +1 -1
  64. edc_appointment/creators/unscheduled_appointment_creator.py +12 -13
  65. edc_appointment/form_validator_mixins/next_appointment_crf_form_validator_mixin.py +1 -3
  66. edc_appointment/form_validator_mixins/window_period_form_validator_mixin.py +7 -6
  67. edc_appointment/form_validators/appointment_form_validator.py +2 -4
  68. edc_appointment/form_validators/utils.py +4 -4
  69. edc_appointment/managers.py +4 -4
  70. edc_appointment/model_mixins/appointment_methods_model_mixin.py +2 -2
  71. edc_appointment/model_mixins/appointment_model_mixin.py +5 -5
  72. edc_appointment/model_mixins/window_period_model_mixin.py +1 -1
  73. edc_appointment/models/appointment.py +1 -1
  74. edc_appointment/skip_appointments.py +5 -6
  75. edc_appointment/stubs.py +12 -12
  76. edc_appointment/utils.py +41 -47
  77. edc_appointment/view_utils/appointment_button.py +3 -5
  78. edc_auth/admin/role_admin.py +5 -7
  79. edc_auth/auth_objects/default_roles.py +1 -3
  80. edc_auth/auth_updater/auth_updater.py +5 -7
  81. edc_auth/auth_updater/group_updater.py +8 -8
  82. edc_auth/auth_updater/role_updater.py +1 -2
  83. edc_auth/get_app_codenames.py +1 -3
  84. edc_auth/import_users.py +19 -19
  85. edc_auth/models/role.py +4 -3
  86. edc_auth/password_setter.py +6 -7
  87. edc_auth/send_new_credentials_to_user.py +2 -3
  88. edc_auth/site_auths.py +3 -3
  89. edc_consent/actions.py +4 -5
  90. edc_consent/consent_definition.py +8 -11
  91. edc_consent/consent_definition_extension.py +3 -3
  92. edc_consent/form_validators/__init__.py +1 -1
  93. edc_consent/model_mixins/__init__.py +2 -2
  94. edc_consent/model_mixins/consent_version_model_mixin.py +1 -1
  95. edc_consent/modeladmin_mixins/consent_model_admin_mixin.py +1 -2
  96. edc_consent/modelform_mixins/consent_modelform_mixin/consent_modelform_validation_mixin.py +3 -5
  97. edc_consent/site_consents.py +10 -15
  98. edc_consent/stubs.py +2 -2
  99. edc_consent/utils.py +1 -1
  100. edc_constants/utils.py +2 -4
  101. edc_crf/crf_form_validator_mixins.py +2 -2
  102. edc_crf/model_mixins/crf_no_manager_model_mixin.py +2 -2
  103. edc_crf/model_mixins/crf_status_model_mixin.py +1 -1
  104. edc_crf/models/crf_status.py +10 -12
  105. edc_crf/update_crf_status_command.py +1 -3
  106. edc_dashboard/management/commands/update_search_slugs.py +8 -11
  107. edc_dashboard/templatetags/edc_dashboard_extras.py +1 -1
  108. edc_dashboard/url_config.py +3 -3
  109. edc_dashboard/utils.py +3 -4
  110. edc_dashboard/views/dashboard_view.py +1 -1
  111. edc_data_manager/models/data_dictionary.py +1 -2
  112. edc_data_manager/models/data_query.py +3 -3
  113. edc_data_manager/models/query_rule.py +2 -2
  114. edc_data_manager/tasks.py +0 -2
  115. edc_device/device.py +1 -1
  116. edc_device/view_mixins.py +1 -1
  117. edc_document_status/fieldsets.py +1 -3
  118. edc_document_status/model_mixins.py +2 -2
  119. edc_document_status/modeladmin_mixins.py +1 -4
  120. edc_egfr/admin/egfr_drop_notification_admin_mixin.py +5 -7
  121. edc_egfr/egfr.py +6 -7
  122. edc_egfr/get_drop_notification_model.py +1 -1
  123. edc_egfr/model_mixins/egfr_drop_notification_model_mixin.py +1 -1
  124. edc_export/archive_exporter.py +26 -27
  125. edc_export/exportables.py +2 -3
  126. edc_export/management/commands/import_receipts.py +6 -6
  127. edc_export/model_exporter/file_history_updater.py +1 -1
  128. edc_export/model_exporter/model_exporter.py +1 -1
  129. edc_export/model_exporter/value_getter.py +6 -6
  130. edc_export/model_mixins/notification_model_mixin.py +4 -4
  131. edc_export/models/data_request.py +3 -3
  132. edc_export/models/data_request_history.py +2 -2
  133. edc_export/models/export_receipt.py +1 -1
  134. edc_export/models/file_history.py +5 -5
  135. edc_export/models/plan.py +4 -4
  136. edc_export/models/upload_export_receipt_file.py +2 -2
  137. edc_export/utils.py +1 -1
  138. edc_facility/facility.py +6 -6
  139. edc_facility/holidays.py +2 -5
  140. edc_facility/import_holidays.py +6 -6
  141. edc_facility/model_mixins.py +1 -1
  142. edc_facility/models/holiday.py +1 -1
  143. edc_facility/utils.py +3 -3
  144. edc_fieldsets/fieldsets.py +1 -1
  145. edc_form_describer/forms_reference.py +5 -8
  146. edc_form_describer/make_forms_reference.py +1 -1
  147. edc_form_describer/management/commands/make_forms_reference.py +1 -1
  148. edc_form_label/custom_label_condition.py +1 -1
  149. edc_form_label/form_label.py +2 -2
  150. edc_form_runners/exceptions.py +1 -1
  151. edc_form_runners/models/issue.py +3 -2
  152. edc_form_runners/site.py +2 -2
  153. edc_form_runners/templatetags/form_runners_extras.py +1 -1
  154. edc_form_runners/utils.py +5 -5
  155. edc_form_validators/applicable_field_validator.py +32 -32
  156. edc_form_validators/base_form_validator.py +1 -1
  157. edc_form_validators/extra_mixins/study_day_form_validator.py +1 -1
  158. edc_form_validators/many_to_many_field_validator.py +38 -43
  159. edc_form_validators/other_specify_field_validator.py +9 -17
  160. edc_form_validators/required_field_validator.py +34 -39
  161. edc_form_validators/test_case_mixin.py +5 -5
  162. edc_identifier/admin.py +1 -3
  163. edc_identifier/identifier.py +2 -3
  164. edc_identifier/model_mixins.py +5 -8
  165. edc_identifier/research_identifier.py +10 -12
  166. edc_identifier/short_identifier.py +1 -1
  167. edc_identifier/simple_identifier.py +22 -22
  168. edc_identifier/utils.py +1 -1
  169. edc_lab/admin/fieldsets.py +7 -9
  170. edc_lab/admin/modeladmin_mixins.py +5 -6
  171. edc_lab/form_validators/requisition_form_validator_mixin.py +2 -3
  172. edc_lab/forms/box_form.py +5 -11
  173. edc_lab/identifiers/aliquot_identifier.py +5 -8
  174. edc_lab/identifiers/prefix.py +2 -5
  175. edc_lab/lab/aliquot_creator.py +1 -2
  176. edc_lab/lab/aliquot_type.py +2 -4
  177. edc_lab/lab/manifest.py +5 -7
  178. edc_lab/lab/requisition_panel.py +2 -4
  179. edc_lab/lab/requisition_panel_group.py +5 -7
  180. edc_lab/model_mixins/requisition/requisition_model_mixin.py +5 -4
  181. edc_lab/model_mixins/shipping/manifest_model_mixin.py +6 -6
  182. edc_lab/model_mixins/shipping/verify_model_mixin.py +4 -3
  183. edc_lab/models/aliquot.py +1 -1
  184. edc_lab/models/box.py +2 -2
  185. edc_lab/models/box_item.py +1 -1
  186. edc_lab/models/box_type.py +1 -1
  187. edc_lab/models/manifest/manifest_item.py +1 -1
  188. edc_lab/pdf_reports/manifest_pdf_report.py +3 -7
  189. edc_lab/site_labs.py +3 -3
  190. edc_lab_dashboard/dashboard_templates.py +1 -1
  191. edc_lab_dashboard/view_mixins/box_view_mixin.py +4 -9
  192. edc_lab_dashboard/views/action_views/action_view.py +1 -2
  193. edc_lab_dashboard/views/action_views/manage_manifest_view.py +1 -1
  194. edc_lab_dashboard/views/action_views/manifest_view.py +9 -11
  195. edc_lab_dashboard/views/action_views/pack_view.py +11 -14
  196. edc_lab_results/calculate_missing.py +2 -2
  197. edc_lab_results/fieldsets.py +6 -6
  198. edc_lab_results/model_mixin_factories/__init__.py +2 -2
  199. edc_lab_results/model_mixin_factories/reportable_result_model_mixin_factory.py +7 -9
  200. edc_lab_results/model_mixin_factories/result_model_mixin_factory.py +7 -9
  201. edc_lab_results/model_mixins/fbg_model_mixin.py +1 -1
  202. edc_lab_results/model_mixins/glucose_model_mixin.py +1 -1
  203. edc_label/admin.py +1 -3
  204. edc_label/label.py +2 -4
  205. edc_label/label_template.py +1 -1
  206. edc_label/subject_label.py +1 -3
  207. edc_list_data/admin.py +3 -5
  208. edc_list_data/load_list_data.py +1 -1
  209. edc_list_data/load_model_data.py +1 -3
  210. edc_list_data/model_mixins.py +3 -5
  211. edc_list_data/preload_data.py +2 -4
  212. edc_list_data/site_list_data.py +6 -7
  213. edc_listboard/filters/listboard_filter.py +2 -2
  214. edc_listboard/views/listboard_view.py +1 -3
  215. edc_locator/models.py +2 -2
  216. edc_locator/view_mixins/subject_locator_view_mixins.py +2 -2
  217. edc_ltfu/action_items.py +1 -1
  218. edc_ltfu/model_mixins.py +0 -2
  219. edc_ltfu/models.py +4 -4
  220. edc_metadata/admin/modeladmin_mixins.py +1 -1
  221. edc_metadata/admin/requisition_metadata.py +2 -4
  222. edc_metadata/metadata/crf_metadata_getter.py +1 -3
  223. edc_metadata/metadata/requisition_metadata_getter.py +1 -3
  224. edc_metadata/metadata_handler.py +2 -2
  225. edc_metadata/metadata_helper/metadata_helper_mixin.py +2 -3
  226. edc_metadata/metadata_mixins/source_model_metadata_mixin.py +2 -2
  227. edc_metadata/metadata_refresher.py +1 -1
  228. edc_metadata/metadata_rules/crf/crf_rule_group.py +3 -5
  229. edc_metadata/metadata_rules/logic.py +1 -1
  230. edc_metadata/metadata_rules/requisition/requisition_rule.py +4 -4
  231. edc_metadata/metadata_rules/requisition/requisition_rule_group.py +2 -2
  232. edc_metadata/metadata_rules/rule_evaluator.py +5 -6
  233. edc_metadata/metadata_rules/rule_group_metaclass.py +2 -3
  234. edc_metadata/metadata_rules/site.py +6 -7
  235. edc_metadata/metadata_updater.py +2 -2
  236. edc_metadata/metadata_wrappers/metadata_wrapper.py +4 -4
  237. edc_metadata/model_mixins/creates/creates_metadata_model_mixin.py +6 -7
  238. edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +2 -2
  239. edc_metadata/model_mixins/updates/updates_metadata_model_mixin.py +2 -2
  240. edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +2 -2
  241. edc_metadata/models/crf_metadata.py +27 -29
  242. edc_metadata/models/crf_metadata_model_mixin.py +1 -1
  243. edc_metadata/models/requisition_metadata.py +29 -31
  244. edc_metadata/stubs.py +17 -17
  245. edc_metadata/utils.py +4 -4
  246. edc_model/__init__.py +2 -2
  247. edc_model/models/historical_records.py +2 -2
  248. edc_model/models/signals.py +1 -1
  249. edc_model/models/url_model_mixin.py +1 -1
  250. edc_model/utils.py +0 -2
  251. edc_model_admin/dashboard/model_admin_dashboard_mixin.py +1 -3
  252. edc_model_admin/history/model_admin_simple_history.py +7 -9
  253. edc_model_admin/mixins/base_model_admin_redirect_mixin.py +4 -6
  254. edc_model_admin/mixins/model_admin_limit_to_selected_foreignkey.py +2 -2
  255. edc_model_admin/mixins/model_admin_model_redirect_mixin.py +2 -10
  256. edc_model_admin/mixins/model_admin_next_url_redirect_mixin.py +8 -9
  257. edc_model_admin/utils.py +6 -9
  258. edc_model_form/mixins/__init__.py +1 -1
  259. edc_model_form/mixins/base_model_form_mixin.py +1 -1
  260. edc_model_to_dataframe/model_to_dataframe.py +2 -4
  261. edc_navbar/site_navbars.py +2 -2
  262. edc_navbar/system_checks.py +1 -1
  263. edc_notification/mailing_list_manager.py +5 -8
  264. edc_notification/management/commands/list_recipients_by_notification.py +1 -1
  265. edc_notification/models/__init__.py +4 -2
  266. edc_notification/notification/graded_event_notification.py +2 -4
  267. edc_notification/notification/model_notification.py +1 -3
  268. edc_notification/notification/notification.py +14 -17
  269. edc_notification/site_notifications.py +7 -7
  270. edc_notification/stubs.py +6 -6
  271. edc_notification/update_mailing_lists_in_m2m.py +2 -2
  272. edc_offstudy/action_items.py +2 -2
  273. edc_offstudy/model_mixins/offstudy_model_mixin.py +1 -1
  274. edc_offstudy/models.py +1 -1
  275. edc_pdf_reports/crf_pdf_report.py +2 -2
  276. edc_pdf_reports/model_mixins.py +2 -2
  277. edc_pdf_reports/report.py +4 -5
  278. edc_pdf_reports/utils.py +1 -1
  279. edc_pdutils/dataframes/get_subject_consent.py +1 -3
  280. edc_pdutils/df_exporters/csv_exporter.py +5 -7
  281. edc_pdutils/df_exporters/tables_exporter.py +2 -2
  282. edc_pdutils/df_handlers/crf_df_handler.py +1 -2
  283. edc_pdutils/dialects/crf_dialect.py +3 -3
  284. edc_pdutils/management/commands/export_models.py +6 -7
  285. edc_pdutils/site_values_mappings.py +2 -2
  286. edc_pdutils/utils/datetime_to_date.py +1 -2
  287. edc_pdutils/utils/refresh_model_from_dataframe.py +1 -3
  288. edc_pdutils/utils/table_names.py +2 -4
  289. edc_pdutils/utils/undash.py +1 -1
  290. edc_pharmacy/admin/medication/assignment_admin.py +2 -4
  291. edc_pharmacy/admin/medication/dosage_guideline_admin.py +2 -4
  292. edc_pharmacy/admin/medication/formulation_admin.py +3 -5
  293. edc_pharmacy/admin/medication/medication_admin.py +3 -5
  294. edc_pharmacy/admin/prescription/rx_refill_admin.py +7 -9
  295. edc_pharmacy/admin/stock/lot_admin.py +5 -7
  296. edc_pharmacy/admin/stock/order_admin.py +2 -2
  297. edc_pharmacy/admin/stock/order_item_admin.py +6 -6
  298. edc_pharmacy/admin/stock/receive_admin.py +1 -1
  299. edc_pharmacy/admin/stock/receive_item_admin.py +2 -2
  300. edc_pharmacy/admin/stock/stock_request_admin.py +4 -6
  301. edc_pharmacy/dosage_calculator.py +4 -4
  302. edc_pharmacy/form_validators/crf/study_medication_form_validator.py +8 -8
  303. edc_pharmacy/forms/stock/stock_request_form.py +2 -4
  304. edc_pharmacy/model_mixins/study_medication_crf_model_mixin.py +2 -2
  305. edc_pharmacy/models/medication/formulation.py +3 -4
  306. edc_pharmacy/models/medication/medication.py +1 -2
  307. edc_pharmacy/models/prescription/rx.py +2 -2
  308. edc_pharmacy/models/prescription/rx_refill.py +7 -9
  309. edc_pharmacy/models/reports/stock_availability.py +3 -4
  310. edc_pharmacy/models/stock/confirmation_at_site.py +1 -3
  311. edc_pharmacy/models/stock/order.py +1 -2
  312. edc_pharmacy/models/stock/receive.py +3 -4
  313. edc_pharmacy/models/stock/receive_item.py +2 -3
  314. edc_pharmacy/models/stock/stock.py +1 -2
  315. edc_pharmacy/models/stock/stock_adjustment.py +1 -2
  316. edc_pharmacy/models/stock/stock_request.py +4 -5
  317. edc_pharmacy/models/storage/box.py +1 -1
  318. edc_pharmacy/models/storage/items/container_model_mixin.py +1 -1
  319. edc_pharmacy/models/storage/room.py +1 -1
  320. edc_pharmacy/models/storage/shelf.py +1 -1
  321. edc_pharmacy/models/storage/utils.py +15 -16
  322. edc_pharmacy/prescribe/create_prescription.py +5 -5
  323. edc_pharmacy/refill/refill_creator.py +1 -1
  324. edc_pharmacy/sample_usb_printing/usb_printing.py +1 -1
  325. edc_pharmacy/utils/__init__.py +1 -1
  326. edc_pharmacy/utils/confirm_stock.py +3 -3
  327. edc_pharmacy/utils/confirm_stock_at_site.py +9 -8
  328. edc_pharmacy/utils/dispense.py +5 -8
  329. edc_pharmacy/utils/format_qty.py +3 -3
  330. edc_pharmacy/utils/get_codenames.py +1 -1
  331. edc_pharmacy/utils/miscellaneous.py +1 -1
  332. edc_pharmacy/utils/process_repack_request.py +18 -19
  333. edc_pharmacy/utils/process_repack_request_queryset.py +0 -2
  334. edc_pharmacy/utils/stock_request/bulk_create_stock_request_items.py +2 -3
  335. edc_pharmacy/views/add_to_storage_bin_view.py +1 -1
  336. edc_pharmacy/views/allocate_to_subject_view.py +2 -6
  337. edc_pharmacy/views/confirm_stock_from_instance_view.py +4 -4
  338. edc_pharmacy/views/confirm_stock_from_queryset_view.py +1 -5
  339. edc_pharmacy/views/confirmation_at_site_view.py +2 -3
  340. edc_pharmacy/views/dispense_view.py +1 -1
  341. edc_pharmacy/views/move_to_storage_bin_view.py +2 -3
  342. edc_pharmacy/views/print_labels_view.py +30 -31
  343. edc_pharmacy/views/transfer_stock_view.py +1 -1
  344. edc_prn/prn.py +1 -1
  345. edc_prn/site_prn_forms.py +1 -2
  346. edc_protocol_incident/action_items.py +2 -2
  347. edc_protocol_incident/model_mixins/protocol_deviation_violation_model_mixin.py +3 -3
  348. edc_protocol_incident/model_mixins/protocol_incident_model_mixin.py +3 -5
  349. edc_protocol_incident/modeladmin_mixins.py +3 -5
  350. edc_protocol_incident/models/protocol_deviation_violation.py +5 -5
  351. edc_protocol_incident/models/protocol_incident.py +5 -5
  352. edc_pylabels/site_label_configs.py +5 -5
  353. edc_qareports/model_mixins/qa_report_model_mixin.py +4 -2
  354. edc_qareports/models/qa_reports_log.py +1 -2
  355. edc_qareports/utils.py +1 -2
  356. edc_randomization/admin.py +3 -5
  357. edc_randomization/auth_objects.py +2 -3
  358. edc_randomization/blinding.py +1 -1
  359. edc_randomization/constants.py +2 -4
  360. edc_randomization/model_mixins.py +3 -3
  361. edc_randomization/randomization_list_importer.py +13 -14
  362. edc_randomization/randomization_list_verifier.py +11 -13
  363. edc_randomization/randomizer.py +2 -2
  364. edc_randomization/system_checks.py +1 -2
  365. edc_randomization/utils.py +5 -5
  366. edc_refusal/admin.py +1 -1
  367. edc_refusal/model_mixins.py +1 -1
  368. edc_refusal/utils.py +1 -1
  369. edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +2 -2
  370. edc_registration/modeladmin_mixins.py +4 -7
  371. edc_registration/models/registered_subject.py +7 -9
  372. edc_registration/utils.py +3 -4
  373. edc_reportable/data/grading_data/daids_july_2017.py +3 -3
  374. edc_reportable/evaluator.py +5 -5
  375. edc_reportable/formula.py +1 -1
  376. edc_reportable/reference_range_evaluator.py +3 -3
  377. edc_reportable/utils/convert_units.py +10 -12
  378. edc_reportable/utils/grading_data_model_cls.py +2 -2
  379. edc_reportable/utils/grading_exception_model_cls.py +2 -2
  380. edc_reportable/utils/molecular_weight_model_cls.py +2 -2
  381. edc_reportable/utils/normal_data_model_cls.py +2 -2
  382. edc_reportable/utils/reference_range_colllection_model_cls.py +2 -2
  383. edc_screening/age_evaluator.py +2 -4
  384. edc_screening/eligibility.py +1 -1
  385. edc_screening/form_validator_mixins.py +2 -2
  386. edc_screening/model_mixins/screening_methods_model_mixin.py +1 -1
  387. edc_screening/screening_eligibility.py +1 -1
  388. edc_screening/utils.py +4 -6
  389. edc_search/model_mixins.py +1 -1
  390. edc_search/search_slug.py +1 -3
  391. edc_search/updater.py +1 -1
  392. edc_sites/admin/site_model_admin_mixin.py +2 -2
  393. edc_sites/model_mixins/site_model_mixin.py +1 -2
  394. edc_sites/modelform_mixins.py +2 -2
  395. edc_sites/models/__init__.py +1 -1
  396. edc_sites/models/site_profile.py +4 -4
  397. edc_sites/site.py +24 -32
  398. edc_sites/system_checks.py +1 -1
  399. edc_sites/utils/get_message_text.py +1 -1
  400. edc_sites/utils/valid_site_for_subject_or_raise.py +5 -6
  401. edc_subject_dashboard/requisition_report.py +4 -5
  402. edc_subject_dashboard/requisition_verifier.py +4 -2
  403. edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +16 -17
  404. edc_subject_dashboard/view_utils/__init__.py +1 -1
  405. edc_subject_dashboard/view_utils/crf_button.py +1 -3
  406. edc_subject_dashboard/view_utils/subject_consent_dashboard_button.py +2 -2
  407. edc_subject_dashboard/view_utils/subject_consent_listboard_button.py +2 -2
  408. edc_subject_dashboard/view_utils/timepoint_status_button.py +1 -4
  409. edc_subject_dashboard/views/requisition_print_actions_view.py +2 -2
  410. edc_subject_dashboard/views/subject_dashboard_view.py +1 -1
  411. edc_timepoint/model_mixins.py +2 -2
  412. edc_transfer/action_items.py +1 -1
  413. edc_transfer/model_mixins.py +4 -3
  414. edc_transfer/modeladmin_mixins.py +3 -6
  415. edc_unblinding/action_items.py +2 -2
  416. edc_unblinding/models/unblinding_request.py +3 -3
  417. edc_unblinding/models/unblinding_review.py +3 -3
  418. edc_utils/__init__.py +6 -5
  419. edc_utils/age.py +1 -1
  420. edc_utils/celery.py +3 -8
  421. edc_utils/get_static_file.py +1 -1
  422. edc_utils/text.py +5 -6
  423. edc_view_utils/__init__.py +3 -3
  424. edc_view_utils/dashboard_model_button.py +4 -4
  425. edc_view_utils/model_button.py +7 -8
  426. edc_view_utils/perms.py +3 -3
  427. edc_visit_schedule/action_items.py +2 -2
  428. edc_visit_schedule/admin/list_filters.py +11 -9
  429. edc_visit_schedule/admin/subject_schedule_history_admin.py +13 -15
  430. edc_visit_schedule/admin/visit_schedule_admin.py +7 -7
  431. edc_visit_schedule/fieldsets.py +4 -6
  432. edc_visit_schedule/management/commands/find_invalid_onschedules.py +1 -1
  433. edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +3 -1
  434. edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +1 -1
  435. edc_visit_schedule/modelform_mixins/__init__.py +1 -1
  436. edc_visit_schedule/modelform_mixins/off_schedule_modelform_mixin.py +1 -2
  437. edc_visit_schedule/models/subject_schedule_history.py +2 -1
  438. edc_visit_schedule/models/visit_schedule.py +2 -2
  439. edc_visit_schedule/schedule/schedule.py +11 -12
  440. edc_visit_schedule/schedule/visit_collection.py +4 -3
  441. edc_visit_schedule/schedule/window.py +19 -12
  442. edc_visit_schedule/site_visit_schedules.py +9 -9
  443. edc_visit_schedule/subject_schedule.py +6 -7
  444. edc_visit_schedule/system_checks.py +1 -1
  445. edc_visit_schedule/view_mixins.py +1 -1
  446. edc_visit_schedule/visit/crf.py +3 -7
  447. edc_visit_schedule/visit/requisition.py +2 -2
  448. edc_visit_schedule/visit/visit.py +6 -7
  449. edc_visit_schedule/visit/window_period.py +8 -8
  450. edc_visit_schedule/visit_schedule/schedules_collection.py +2 -5
  451. edc_visit_tracking/action_items.py +11 -13
  452. edc_visit_tracking/form_validators/visit_form_validator.py +5 -5
  453. edc_visit_tracking/model_mixins/base/visit_methods_model_mixin.py +3 -4
  454. edc_visit_tracking/model_mixins/crfs/visit_tracking_crf_model_mixin.py +2 -2
  455. edc_visit_tracking/model_mixins/subject_visit_missed_model_mixin.py +2 -3
  456. edc_visit_tracking/model_mixins/utils.py +1 -1
  457. edc_visit_tracking/model_mixins/visit_model_mixin/previous_visit_model_mixin.py +2 -2
  458. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +3 -3
  459. edc_visit_tracking/modeladmin_mixins/crf_model_admin_mixin.py +6 -4
  460. edc_visit_tracking/modeladmin_mixins/visit_model_admin_mixin.py +6 -7
  461. edc_visit_tracking/modelform_mixins/crf/visit_tracking_crf_modelform_mixin.py +4 -5
  462. edc_visit_tracking/modelform_mixins/visit_tracking_modelform_mixin.py +3 -4
  463. edc_visit_tracking/models/subject_visit.py +1 -1
  464. edc_visit_tracking/models/subject_visit_missed.py +1 -1
  465. edc_visit_tracking/stubs.py +7 -7
  466. edc_visit_tracking/typing_stubs.py +11 -11
  467. edc_visit_tracking/utils.py +5 -5
  468. edc_visit_tracking/view_utils/related_visit_button.py +5 -5
  469. edc_vitals/calculators/bmi.py +1 -1
  470. edc_vitals/form_validators/blood_pressure_form_validator_mixin.py +8 -10
  471. edc_vitals/form_validators/bmi_form_validator_mixin.py +1 -1
  472. edc_vitals/form_validators/weight_height_with_bmi_form_validator_mixin.py +5 -2
  473. edc_vitals/model_mixins/blood_pressure_model_mixin.py +3 -4
  474. edc_vitals/model_mixins/weight_height_bmi_model_mixin.py +4 -4
  475. edc_vitals/utils.py +1 -1
  476. edc_vitals/validators.py +1 -1
  477. {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/WHEEL +0 -0
  478. {clinicedc-2.0.4.dist-info → clinicedc-2.0.6.dist-info}/licenses/LICENSE +0 -0
@@ -11,6 +11,13 @@ from edc_model.models import BaseUuidModel
11
11
  from ..choices import PRIORITY
12
12
  from ..exceptions import ActionTypeError
13
13
 
14
+ MISSING_ACTION_CLASS = "Model missing an action class. See {reference_model_cls!r}"
15
+ NOT_CONFIGURED_FOR_ACTIONS = (
16
+ "Model not configured for Actions. Are you using the model mixin? "
17
+ "See {reference_model_cls!r}. Got {err}"
18
+ )
19
+ REFERENCE_MODEL_LOOKUP_ERROR = "{err}. Got reference_model=`{reference_model}`"
20
+
14
21
 
15
22
  class ActionTypeManager(models.Manager):
16
23
  use_in_migrations = True
@@ -25,11 +32,17 @@ class ActionType(BaseUuidModel):
25
32
  display_name = models.CharField(max_length=100)
26
33
 
27
34
  reference_model = models.CharField(
28
- max_length=100, null=True, blank=True, help_text="reference model"
35
+ max_length=100,
36
+ blank=True,
37
+ default="",
38
+ help_text="reference model",
29
39
  )
30
40
 
31
41
  related_reference_model = models.CharField(
32
- max_length=100, null=True, blank=True, help_text="origin reference model"
42
+ max_length=100,
43
+ blank=True,
44
+ default="",
45
+ help_text="origin reference model",
33
46
  )
34
47
 
35
48
  priority = models.CharField(max_length=25, choices=PRIORITY, default=HIGH_PRIORITY)
@@ -46,7 +59,7 @@ class ActionType(BaseUuidModel):
46
59
  default=True, help_text="This action may be created by the user"
47
60
  )
48
61
 
49
- instructions = models.TextField(max_length=250, null=True, blank=True)
62
+ instructions = models.TextField(max_length=250, blank=True, default="")
50
63
 
51
64
  objects = ActionTypeManager()
52
65
 
@@ -54,7 +67,7 @@ class ActionType(BaseUuidModel):
54
67
  return self.display_name
55
68
 
56
69
  def natural_key(self) -> tuple:
57
- return (self.name,) # noqa
70
+ return (self.name,)
58
71
 
59
72
  @property
60
73
  def reference_model_cls(self) -> Any:
@@ -63,7 +76,11 @@ class ActionType(BaseUuidModel):
63
76
  try:
64
77
  model_cls = django_apps.get_model(self.reference_model)
65
78
  except (LookupError, ValueError) as e:
66
- raise ActionTypeError(f"{e}. Got reference_model=`{self.reference_model}`")
79
+ raise ActionTypeError(
80
+ REFERENCE_MODEL_LOOKUP_ERROR.format(
81
+ err=str(e), reference_model=self.reference_model
82
+ )
83
+ ) from e
67
84
  return model_cls
68
85
 
69
86
  def save(self, *args, **kwargs):
@@ -72,20 +89,23 @@ class ActionType(BaseUuidModel):
72
89
  try:
73
90
  if not self.reference_model_cls.action_name:
74
91
  raise ActionTypeError(
75
- f"Model missing an action class. See {repr(self.reference_model_cls)}"
92
+ MISSING_ACTION_CLASS.format(
93
+ reference_model_cls=self.reference_model_cls
94
+ )
76
95
  )
77
96
  except AttributeError as e:
78
97
  if "action_name" in str(e):
79
98
  raise ActionTypeError(
80
- f"Model not configured for Actions. Are you using the model mixin? "
81
- f"See {repr(self.reference_model_cls)}. Got {e}"
82
- )
83
- else:
84
- raise
99
+ NOT_CONFIGURED_FOR_ACTIONS.format(
100
+ reference_model_cls=self.reference_model_cls, err=str(e)
101
+ )
102
+ ) from e
103
+ raise
85
104
  super().save(*args, **kwargs)
86
105
 
87
106
  class Meta(BaseUuidModel.Meta):
88
- indexes = BaseUuidModel.Meta.indexes + [
107
+ indexes = (
108
+ *BaseUuidModel.Meta.indexes,
89
109
  models.Index(fields=["id", "name"]),
90
- ]
110
+ )
91
111
  default_permissions = ("add", "change", "delete", "view", "export", "import")
@@ -33,9 +33,10 @@ class Reference(NonUniqueSubjectIdentifierFieldMixin, ActionModelMixin, BaseUuid
33
33
  objects = ReferenceManager()
34
34
 
35
35
  def natural_key(self):
36
- return (self.action_identifier,) # noqa
36
+ return (self.action_identifier,)
37
37
 
38
38
  class Meta(BaseUuidModel.Meta, NonUniqueSubjectIdentifierFieldMixin.Meta):
39
39
  indexes = (
40
- BaseUuidModel.Meta.indexes + NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
40
+ *BaseUuidModel.Meta.indexes,
41
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
41
42
  )
@@ -4,7 +4,7 @@ import copy
4
4
  import sys
5
5
  from dataclasses import InitVar, dataclass, field
6
6
  from importlib import import_module
7
- from typing import TYPE_CHECKING, Type
7
+ from typing import TYPE_CHECKING
8
8
 
9
9
  from django.apps import apps as django_apps
10
10
  from django.core.management.color import color_style
@@ -36,12 +36,12 @@ class SiteActionError(Exception):
36
36
 
37
37
  @dataclass
38
38
  class ActionButton:
39
- action_cls: InitVar[Type[Action] | Type[ActionWithNotification]] = None
39
+ action_cls: InitVar[type[Action] | type[ActionWithNotification]] = None
40
40
  name: str = field(init=False)
41
41
  display_name: str = field(init=False)
42
42
  action_type_id: str = field(init=False)
43
43
 
44
- def __post_init__(self, action_cls: Type[Action] | Type[ActionWithNotification]):
44
+ def __post_init__(self, action_cls: type[Action] | type[ActionWithNotification]):
45
45
  self.name = action_cls.name
46
46
  self.display_name = action_cls.display_name
47
47
  self.action_type_id = str(get_action_type(action_cls).pk)
@@ -49,7 +49,7 @@ class ActionButton:
49
49
 
50
50
  class SiteActionItemCollection:
51
51
  def __init__(self):
52
- self.registry: dict[str, Type[Action] | Type[ActionWithNotification]] = {}
52
+ self.registry: dict[str, type[Action] | type[ActionWithNotification]] = {}
53
53
  self.updated_action_types: bool | None = None
54
54
  prn = Prn(model="edc_action_item.actionitem", url_namespace="edc_action_item_admin")
55
55
  site_prn_forms.register(prn)
@@ -63,7 +63,7 @@ class SiteActionItemCollection:
63
63
  def __iter__(self):
64
64
  return iter(self.registry.values())
65
65
 
66
- def unregister(self, action_cls: Type[Action] | Type[ActionWithNotification]) -> None:
66
+ def unregister(self, action_cls: type[Action] | type[ActionWithNotification]) -> None:
67
67
  if action_cls.name in self.registry:
68
68
  del self.registry[action_cls.name]
69
69
  prn = Prn(
@@ -72,14 +72,13 @@ class SiteActionItemCollection:
72
72
  )
73
73
  site_prn_forms.unregister(prn)
74
74
 
75
- def register(self, action_cls: Type[Action] | Type[ActionWithNotification] = None) -> None:
75
+ def register(self, action_cls: type[Action] | type[ActionWithNotification] = None) -> None:
76
76
  if action_cls.name in self.registry:
77
77
  raise AlreadyRegistered(
78
78
  f"Action class is already registered. Got name='{action_cls.name}' "
79
79
  f"for {action_cls.__name__}"
80
80
  )
81
- else:
82
- self.registry.update({action_cls.name: action_cls})
81
+ self.registry.update({action_cls.name: action_cls})
83
82
  if action_cls.show_link_to_changelist:
84
83
  prn = Prn(
85
84
  model=action_cls.get_reference_model(),
@@ -97,7 +96,7 @@ class SiteActionItemCollection:
97
96
  self.register_notifications(action_cls)
98
97
 
99
98
  @staticmethod
100
- def register_notifications(action_cls: Type[Action] | Type[ActionWithNotification]):
99
+ def register_notifications(action_cls: type[Action] | type[ActionWithNotification]):
101
100
  """Registers a new model notification and an updated model
102
101
  notification for this action cls.
103
102
 
@@ -110,10 +109,10 @@ class SiteActionItemCollection:
110
109
  pass
111
110
 
112
111
  @property
113
- def all(self) -> dict[str, Type[Action] | Type[ActionWithNotification]]:
112
+ def all(self) -> dict[str, type[Action] | type[ActionWithNotification]]:
114
113
  return self.registry
115
114
 
116
- def get(self, name) -> Type[Action] | Type[ActionWithNotification]:
115
+ def get(self, name) -> type[Action] | type[ActionWithNotification]:
117
116
  """Returns an action class."""
118
117
  if name not in self.registry:
119
118
  raise SiteActionError(
@@ -122,14 +121,14 @@ class SiteActionItemCollection:
122
121
  )
123
122
  return self.registry.get(name)
124
123
 
125
- def get_by_model(self, model=None) -> Type[Action] | Type[ActionWithNotification] | None:
124
+ def get_by_model(self, model=None) -> type[Action] | type[ActionWithNotification] | None:
126
125
  """Returns the action_cls linked to this reference model."""
127
126
  for action_cls in self.registry.values():
128
127
  if action_cls.get_reference_model() == model:
129
128
  return self.get(action_cls.name)
130
129
  return None
131
130
 
132
- def get_add_actions_to_show(self) -> dict[str, Type[Action]]:
131
+ def get_add_actions_to_show(self) -> dict[str, type[Action]]:
133
132
  actions = {
134
133
  action_cls.name: action_cls
135
134
  for action_cls in self.registry.values()
@@ -164,7 +163,7 @@ class SiteActionItemCollection:
164
163
  except ImportError as e:
165
164
  site_action_items.registry = before_import_registry
166
165
  if module_has_submodule(mod, module_name):
167
- raise SiteActionError(str(e))
166
+ raise SiteActionError(str(e)) from e
168
167
  except ImportError:
169
168
  pass
170
169
  # except Exception as e:
edc_action_item/stubs.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional, Protocol, Type
1
+ from typing import Optional, Protocol
2
2
  from uuid import UUID
3
3
 
4
4
  from django.db import models
@@ -8,20 +8,20 @@ class ActionStub(Protocol):
8
8
  def __init__(
9
9
  self,
10
10
  action_item: Optional["ActionItemStub"] = None,
11
- reference_obj: Optional[models.Model] = None,
11
+ reference_obj: models.Model | None = None,
12
12
  subject_identifier: str = None,
13
13
  action_identifier: str = None,
14
14
  parent_action_item: Optional["ActionItemStub"] = None,
15
15
  related_action_item: Optional["ActionItemStub"] = None,
16
- using: Optional[str] = None,
17
- readonly: Optional[bool] = None,
16
+ using: str | None = None,
17
+ readonly: bool | None = None,
18
18
  ) -> None: ...
19
19
 
20
20
  name: str
21
21
  action_item: "ActionItemStub"
22
22
  action_identifier: str
23
- related_reference_model: Optional[str]
24
- related_reference_fk_attr: Optional[str]
23
+ related_reference_model: str | None
24
+ related_reference_fk_attr: str | None
25
25
  subject_identifier: str
26
26
  related_action_item: Optional["ActionItemStub"]
27
27
  ...
@@ -30,8 +30,8 @@ class ActionStub(Protocol):
30
30
  class ActionTypeStub(Protocol):
31
31
  name: str
32
32
  display_name: str
33
- reference_model: Optional[str]
34
- related_reference_model: Optional[str]
33
+ reference_model: str | None
34
+ related_reference_model: str | None
35
35
  ...
36
36
 
37
37
 
@@ -53,7 +53,7 @@ class ActionItemStub(Protocol):
53
53
 
54
54
  def get_status_display(self) -> str: ...
55
55
 
56
- def get_action_cls(self) -> Type[ActionStub]: ...
56
+ def get_action_cls(self) -> type[ActionStub]: ...
57
57
 
58
58
 
59
59
  class ActionItemWithNotificationStub(ActionItemStub, Protocol):
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Type
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from django import template
6
6
 
@@ -74,7 +74,7 @@ def add_action_item_popover(
74
74
  `Add action linked PRN forms`
75
75
  """
76
76
  action_item_add_url: str = "edc_action_item_admin:edc_action_item_actionitem_add"
77
- add_actions: dict[str, Type[Action]] = site_action_items.get_add_actions_to_show()
77
+ add_actions: dict[str, type[Action]] = site_action_items.get_add_actions_to_show()
78
78
  if add_actions:
79
79
  d = {k: v.display_name for k, v in add_actions.items()}
80
80
  add_actions = {}
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import TYPE_CHECKING, Type
4
+ from typing import TYPE_CHECKING
5
5
  from uuid import UUID
6
6
 
7
7
  from django.contrib.sites.models import Site
@@ -18,9 +18,9 @@ if TYPE_CHECKING:
18
18
 
19
19
  @dataclass(kw_only=True)
20
20
  class ActionItemButton(ModelButton):
21
- action_cls: Type[Action] = None
21
+ action_cls: type[Action] = None
22
22
  model_obj: ActionItem | None = None
23
- model_cls: Type[ActionItem] = field(default=None)
23
+ model_cls: type[ActionItem] = field(default=None)
24
24
  appointment: Appointment = None
25
25
  next_url_name: str = field(default="subject_dashboard_url")
26
26
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import TYPE_CHECKING, Type
4
+ from typing import TYPE_CHECKING
5
5
  from uuid import UUID
6
6
 
7
7
  from django.core.exceptions import ObjectDoesNotExist
@@ -17,9 +17,9 @@ if TYPE_CHECKING:
17
17
 
18
18
  class PrnModel(BaseUuidModel):
19
19
  subject_identifier: str
20
- ... # noqa
20
+ ...
21
21
 
22
- class CrfModel(CrfModelMixin): ... # noqa
22
+ class CrfModel(CrfModelMixin): ...
23
23
 
24
24
 
25
25
  @dataclass
@@ -28,7 +28,7 @@ class ActionItemPopoverListItem(PrnButton):
28
28
  category: str = None
29
29
  appointment: Appointment | None = None
30
30
  model_obj: PrnModel | CrfModel | None = field(default=None, init=False)
31
- model_cls: Type[PrnModel | CrfModel | None] = field(default=None, init=False)
31
+ model_cls: type[PrnModel | CrfModel | None] = field(default=None, init=False)
32
32
 
33
33
  def __post_init__(self):
34
34
  if self.category == "reference":
@@ -7,7 +7,7 @@ from edc_constants.constants import NEVER, OTHER, YES
7
7
 
8
8
  class MedicationAdherenceFormValidatorMixin:
9
9
  def clean(self: Any):
10
- # super()._clean() # noqa
10
+ # super()._clean()
11
11
  self.confirm_visual_scores_match()
12
12
  self.required_if(
13
13
  YES,
@@ -35,7 +35,7 @@ class AeFollowupAction(ActionWithNotification):
35
35
  name = AE_FOLLOWUP_ACTION
36
36
  display_name = "Submit AE Followup Report"
37
37
  notification_display_name = "AE Followup Report"
38
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION]
38
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION)
39
39
  related_reference_fk_attr = "ae_initial"
40
40
  create_by_user = False
41
41
  show_link_to_changelist = True
@@ -15,7 +15,7 @@ class AeInitialAction(ActionWithNotification):
15
15
  name = AE_INITIAL_ACTION
16
16
  display_name = "Submit AE Initial Report"
17
17
  notification_display_name = "AE Initial Report"
18
- parent_action_names = []
18
+ parent_action_names = ()
19
19
  reference_model = f"{ADVERSE_EVENT_APP_LABEL}.aeinitial"
20
20
  show_link_to_changelist = True
21
21
  show_link_to_add = True
@@ -13,7 +13,7 @@ class AeSusarAction(ActionWithNotification):
13
13
  name = AE_SUSAR_ACTION
14
14
  display_name = "Submit AE SUSAR Report"
15
15
  notification_display_name = "AE SUSAR Report"
16
- parent_action_names = [AE_INITIAL_ACTION]
16
+ parent_action_names = (AE_INITIAL_ACTION,)
17
17
  reference_model = f"{ADVERSE_EVENT_APP_LABEL}.aesusar"
18
18
  related_reference_model = f"{ADVERSE_EVENT_APP_LABEL}.aeinitial"
19
19
  related_reference_fk_attr = "ae_initial"
@@ -13,7 +13,7 @@ class AeTmgAction(ActionWithNotification):
13
13
  name = AE_TMG_ACTION
14
14
  display_name = "TMG AE Report pending"
15
15
  notification_display_name = "TMG AE Report"
16
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION, AE_TMG_ACTION]
16
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION, AE_TMG_ACTION)
17
17
  reference_model = f"{ADVERSE_EVENT_APP_LABEL}.aetmg"
18
18
  related_reference_model = f"{ADVERSE_EVENT_APP_LABEL}.aeinitial"
19
19
  related_reference_fk_attr = "ae_initial"
@@ -17,12 +17,11 @@ class DeathReportAction(ActionWithNotification):
17
17
  name = DEATH_REPORT_ACTION
18
18
  display_name = "Submit Death Report"
19
19
  notification_display_name = "Death Report"
20
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION]
20
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION)
21
21
  show_link_to_changelist = True
22
22
  show_link_to_add = True
23
23
  priority = HIGH_PRIORITY
24
24
  singleton = True
25
- dirty_fields = ["cause_of_death"]
26
25
  enable_tmg_workflow = True
27
26
 
28
27
  reference_model = f"{ADVERSE_EVENT_APP_LABEL}.deathreport"
@@ -14,7 +14,7 @@ class DeathReportTmgAction(ActionWithNotification):
14
14
  name = DEATH_REPORT_TMG_ACTION
15
15
  display_name = "TMG Death Report (1st) pending"
16
16
  notification_display_name = "TMG Death Report (1st)"
17
- parent_action_names = [DEATH_REPORT_ACTION]
17
+ parent_action_names = (DEATH_REPORT_ACTION,)
18
18
  related_reference_fk_attr = "death_report"
19
19
  priority = HIGH_PRIORITY
20
20
  create_by_user = False
@@ -13,7 +13,7 @@ class DeathReportTmgSecondAction(ActionWithNotification):
13
13
  name = DEATH_REPORT_TMG_SECOND_ACTION
14
14
  display_name = "TMG Death Report (2nd) pending"
15
15
  notification_display_name = "TMG Death Report (2nd)"
16
- parent_action_names = [DEATH_REPORT_TMG_ACTION]
16
+ parent_action_names = (DEATH_REPORT_TMG_ACTION,)
17
17
  related_reference_fk_attr = "death_report"
18
18
  priority = HIGH_PRIORITY
19
19
  create_by_user = False
@@ -11,7 +11,7 @@ class HospitalizationAction(ActionWithNotification):
11
11
  name = HOSPITALIZATION_ACTION
12
12
  display_name = "Submit Hospitalization Report"
13
13
  notification_display_name = "Hospitalization"
14
- parent_action_names = []
14
+ parent_action_names = ()
15
15
  show_link_to_changelist = True
16
16
  show_link_to_add = True
17
17
  priority = HIGH_PRIORITY
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Optional
3
+ from typing import TYPE_CHECKING, Any
4
4
  from zoneinfo import ZoneInfo
5
5
 
6
6
  from django import forms
@@ -56,7 +56,7 @@ class DeathReportFormValidatorMixin:
56
56
 
57
57
  def validate_study_day_with_death_report_date(
58
58
  self: Any,
59
- subject_identifier: Optional[str] = None,
59
+ subject_identifier: str | None = None,
60
60
  ) -> None:
61
61
  """Raises an exception if study day does not match
62
62
  calculation against ZoneInfo.
@@ -73,7 +73,7 @@ class DeathReportFormValidatorMixin:
73
73
  or self.instance.subject_identifier
74
74
  )
75
75
  if not subject_identifier:
76
- raise ValueError(f"Subject identifier cannot be None. See {repr(self)}")
76
+ raise ValueError(f"Subject identifier cannot be None. See {self!r}")
77
77
  registered_subject_model_cls = django_apps.get_model(
78
78
  "edc_registration.registeredsubject"
79
79
  )
@@ -56,7 +56,7 @@ class BaseRequiresDeathReportFormValidatorMixin:
56
56
  instance.
57
57
  """
58
58
  death_report = self.death_report_or_raises
59
- value = getattr(death_report, getattr(death_report, "death_date_field"))
59
+ value = getattr(death_report, death_report.death_date_field)
60
60
 
61
61
  try:
62
62
  death_report_date = value.astimezone(ZoneInfo("UTC")).date()
@@ -105,7 +105,7 @@ class RequiresDeathReportFormValidatorMixin(BaseRequiresDeathReportFormValidator
105
105
  "death report form first."
106
106
  }
107
107
  )
108
- elif (
108
+ if (
109
109
  self.cleaned_data.get(self.offschedule_reason_field).name != DEAD
110
110
  and self.death_report
111
111
  ):
@@ -125,7 +125,7 @@ class RequiresDeathReportFormValidatorMixin(BaseRequiresDeathReportFormValidator
125
125
  )
126
126
  }
127
127
  )
128
- elif self.cleaned_data.get(self.death_date_field) and self.death_report:
128
+ if self.cleaned_data.get(self.death_date_field) and self.death_report:
129
129
  self.match_date_of_death_or_raise()
130
130
 
131
131
  def match_date_of_death_or_raise(self) -> None:
@@ -153,4 +153,3 @@ class RequiresDeathReportFormValidatorMixin(BaseRequiresDeathReportFormValidator
153
153
  )
154
154
  }
155
155
  )
156
- return None
@@ -27,7 +27,7 @@ class DeathReportTmgFormValidator(
27
27
  )
28
28
  except ObjectDoesNotExist:
29
29
  self.raise_validation_error("Death report not found.", INVALID_ERROR)
30
- death_date = getattr(obj, getattr(obj, "death_date_field"))
30
+ death_date = getattr(obj, obj.death_date_field)
31
31
  try:
32
32
  death_date = death_date.date()
33
33
  except AttributeError:
@@ -7,6 +7,9 @@ class AeFollowupMethodsModelMixin(models.Model):
7
7
  def __str__(self):
8
8
  return f"{self.action_identifier[-9:]}"
9
9
 
10
+ class Meta:
11
+ abstract = True
12
+
10
13
  def save(self, *args, **kwargs):
11
14
  self.subject_identifier = self.ae_initial.subject_identifier
12
15
  super().save(*args, **kwargs)
@@ -27,6 +30,3 @@ class AeFollowupMethodsModelMixin(models.Model):
27
30
 
28
31
  def get_action_item_reason(self):
29
32
  return self.ae_initial.ae_description
30
-
31
- class Meta:
32
- abstract = True
@@ -35,7 +35,7 @@ class AeFollowupModelMixin(
35
35
  abstract = True
36
36
  verbose_name = "AE Follow-up Report"
37
37
  indexes = (
38
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
39
- + ActionModelMixin.Meta.indexes
40
- + [models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])]
38
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
39
+ *ActionModelMixin.Meta.indexes,
40
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
41
41
  )
@@ -50,7 +50,6 @@ class AeInitialFieldsModelMixin(models.Model):
50
50
  verbose_name="Relation to study drug:",
51
51
  max_length=25,
52
52
  choices=STUDY_DRUG_RELATIONSHIP,
53
- null=True,
54
53
  )
55
54
 
56
55
  class Meta:
@@ -3,6 +3,9 @@ from django.db import models
3
3
 
4
4
 
5
5
  class AeInitialMethodsModelMixin(models.Model):
6
+ class Meta:
7
+ abstract = True
8
+
6
9
  def __str__(self):
7
10
  return f"{self.action_identifier[-9:]} Grade {self.ae_grade}"
8
11
 
@@ -26,6 +29,3 @@ class AeInitialMethodsModelMixin(models.Model):
26
29
  def description(self):
27
30
  """Returns a description."""
28
31
  return f"{self.action_identifier[-9:]} Grade-{self.ae_grade}. {self.ae_description}"
29
-
30
- class Meta:
31
- abstract = True
@@ -44,7 +44,7 @@ class AeInitialModelMixin(
44
44
  abstract = True
45
45
  verbose_name = "AE Initial Report"
46
46
  indexes = (
47
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
48
- + ActionModelMixin.Meta.indexes
49
- + [models.Index(fields=["subject_identifier", "action_identifier", "site"])]
47
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
48
+ *ActionModelMixin.Meta.indexes,
49
+ models.Index(fields=["subject_identifier", "action_identifier", "site"]),
50
50
  )
@@ -2,6 +2,9 @@ from django.db import models
2
2
 
3
3
 
4
4
  class AesiMethodsModelMixin(models.Model):
5
+ class Meta:
6
+ abstract = True
7
+
5
8
  def __str__(self):
6
9
  return f"{self.action_identifier[-9:]}"
7
10
 
@@ -10,7 +13,4 @@ class AesiMethodsModelMixin(models.Model):
10
13
  super().save(*args, **kwargs)
11
14
 
12
15
  def natural_key(self):
13
- return (self.action_identifier,) # noqa
14
-
15
- class Meta:
16
- abstract = True
16
+ return (self.action_identifier,)
@@ -33,7 +33,7 @@ class AesiModelMixin(
33
33
  abstract = True
34
34
  verbose_name = "AE of Special Interest Report"
35
35
  indexes = (
36
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
37
- + ActionModelMixin.Meta.indexes
38
- + [models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])]
36
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
37
+ *ActionModelMixin.Meta.indexes,
38
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
39
39
  )
@@ -4,6 +4,9 @@ from edc_constants.constants import CLOSED, OPEN
4
4
 
5
5
 
6
6
  class AeSusarMethodsModelMixin(models.Model):
7
+ class Meta:
8
+ abstract = True
9
+
7
10
  def __str__(self):
8
11
  return f"{self.action_identifier[-9:]}"
9
12
 
@@ -18,7 +21,4 @@ class AeSusarMethodsModelMixin(models.Model):
18
21
  super().save(*args, **kwargs)
19
22
 
20
23
  def natural_key(self):
21
- return (self.action_identifier,) # noqa
22
-
23
- class Meta:
24
- abstract = True
24
+ return (self.action_identifier,)
@@ -34,7 +34,7 @@ class AeSusarModelMixin(
34
34
  verbose_name = "AE SUSAR Report"
35
35
  verbose_name_plural = "AE SUSAR Reports"
36
36
  indexes = (
37
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
38
- + ActionModelMixin.Meta.indexes
39
- + [models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])]
37
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
38
+ *ActionModelMixin.Meta.indexes,
39
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
40
40
  )