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
@@ -41,13 +41,13 @@ class AeTmgFieldsModelMixin(models.Model):
41
41
  verbose_name="Date and time of clinical review: ",
42
42
  )
43
43
 
44
- ae_description = models.TextField(blank=True, null=True, verbose_name="Description of AE:")
44
+ ae_description = models.TextField(blank=True, verbose_name="Description of AE:")
45
45
 
46
46
  investigator_comments = models.TextField(
47
- blank=True, null=True, verbose_name="This investigator's comments:"
47
+ blank=True, verbose_name="This investigator's comments:"
48
48
  )
49
49
 
50
- ae_classification = models.CharField(max_length=150, blank=True, null=True)
50
+ ae_classification = models.CharField(max_length=150, blank=True)
51
51
 
52
52
  ae_classification_other = OtherCharField(max_length=250, blank=True, null=True)
53
53
 
@@ -56,11 +56,10 @@ class AeTmgFieldsModelMixin(models.Model):
56
56
  max_length=15,
57
57
  choices=YES_NO,
58
58
  blank=False,
59
- null=True,
60
59
  help_text="If No, explain in the narrative below",
61
60
  )
62
61
 
63
- investigator_narrative = models.TextField(verbose_name="Narrative", blank=True, null=True)
62
+ investigator_narrative = models.TextField(verbose_name="Narrative", blank=True)
64
63
 
65
64
  investigator_ae_classification_agreed = models.CharField(
66
65
  verbose_name=(
@@ -2,6 +2,9 @@ from django.db import models
2
2
 
3
3
 
4
4
  class AeTmgMethodsModelMixin(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,7 @@ class AeTmgMethodsModelMixin(models.Model):
10
13
  super().save(*args, **kwargs)
11
14
 
12
15
  def natural_key(self):
13
- return (self.action_identifier,) # noqa
16
+ return (self.action_identifier,)
14
17
 
15
18
  def get_action_item_reason(self):
16
19
  return self.ae_initial.ae_description
@@ -20,6 +23,3 @@ class AeTmgMethodsModelMixin(models.Model):
20
23
  fields.append("subject_identifier")
21
24
  fields.append("report_status")
22
25
  return fields
23
-
24
- class Meta:
25
- abstract = True
@@ -36,7 +36,7 @@ class AeTmgModelMixin(
36
36
  verbose_name = "AE TMG Report"
37
37
  verbose_name_plural = "AE TMG Reports"
38
38
  indexes = (
39
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
40
- + ActionModelMixin.Meta.indexes
41
- + [models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])]
39
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
40
+ *ActionModelMixin.Meta.indexes,
41
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
42
42
  )
@@ -22,14 +22,14 @@ class DeathReportExtraFieldsModelMixin(models.Model):
22
22
 
23
23
  hospital_death = models.CharField(
24
24
  verbose_name=(
25
- "Did the participant die in hospital, or die just after " "visiting a hospital?"
25
+ "Did the participant die in hospital, or die just after visiting a hospital?"
26
26
  ),
27
27
  max_length=50,
28
28
  choices=YES_NO,
29
29
  )
30
30
 
31
31
  hospital_name = models.CharField(
32
- verbose_name="Which hospital was this", max_length=50, null=True, blank=True
32
+ verbose_name="Which hospital was this", max_length=50, blank=True
33
33
  )
34
34
 
35
35
  informant = models.CharField(
@@ -50,7 +50,6 @@ class DeathReportExtraFieldsModelMixin(models.Model):
50
50
 
51
51
  comment = models.TextField(
52
52
  verbose_name="Comment",
53
- null=True,
54
53
  blank=True,
55
54
  help_text="Provide any additional details, if relevant",
56
55
  )
@@ -69,7 +69,6 @@ class DeathReportModelMixin(
69
69
  choices=YES_NO,
70
70
  max_length=5,
71
71
  verbose_name="Death as inpatient",
72
- null=True,
73
72
  blank=False,
74
73
  )
75
74
 
@@ -78,7 +77,7 @@ class DeathReportModelMixin(
78
77
  on_delete=PROTECT,
79
78
  verbose_name="Main cause of death",
80
79
  help_text=(
81
- "Main cause of death in the opinion of the " "local study doctor and local PI"
80
+ "Main cause of death in the opinion of the local study doctor and local PI"
82
81
  ),
83
82
  null=True,
84
83
  blank=False,
@@ -86,7 +85,7 @@ class DeathReportModelMixin(
86
85
 
87
86
  cause_of_death_other = OtherCharField(max_length=100, blank=True, null=True)
88
87
 
89
- narrative = models.TextField(verbose_name="Narrative", blank=False, null=True)
88
+ narrative = models.TextField(verbose_name="Narrative", blank=False)
90
89
 
91
90
  objects = ActionIdentifierModelManager()
92
91
 
@@ -94,11 +93,6 @@ class DeathReportModelMixin(
94
93
 
95
94
  history = HistoricalRecords(inherit=True)
96
95
 
97
- def natural_key(self):
98
- return (self.action_identifier,) # noqa
99
-
100
- natural_key.dependencies = ["edc_adverse_event.causeofdeath"]
101
-
102
96
  class Meta(
103
97
  SiteModelMixin.Meta,
104
98
  UniqueSubjectIdentifierFieldMixin.Meta,
@@ -107,6 +101,12 @@ class DeathReportModelMixin(
107
101
  abstract = True
108
102
  verbose_name = "Death Report"
109
103
  verbose_name_plural = "Death Reports"
110
- indexes = ActionNoManagersModelMixin.Meta.indexes + [
111
- models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])
112
- ]
104
+ indexes = (
105
+ *ActionNoManagersModelMixin.Meta.indexes,
106
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
107
+ )
108
+
109
+ def natural_key(self):
110
+ return (self.action_identifier,)
111
+
112
+ natural_key.dependencies = ("edc_adverse_event.causeofdeath",)
@@ -59,7 +59,7 @@ class DeathReportTmgFieldsModelMixin(models.Model):
59
59
  on_delete=PROTECT,
60
60
  verbose_name="Main cause of death",
61
61
  help_text=(
62
- "Main cause of death in the opinion of the " "local study doctor and local PI"
62
+ "Main cause of death in the opinion of the local study doctor and local PI"
63
63
  ),
64
64
  null=True,
65
65
  )
@@ -68,24 +68,25 @@ class DeathReportTmgFieldsModelMixin(models.Model):
68
68
  verbose_name='If "Other" above, please specify',
69
69
  max_length=100,
70
70
  blank=True,
71
- null=True,
72
71
  )
73
72
 
74
73
  cause_of_death_agreed = models.CharField(
75
74
  verbose_name="Is the cause of death agreed between study doctor and TMG member?",
76
75
  max_length=15,
77
76
  choices=YES_NO,
78
- null=True,
79
77
  help_text="If No, explain in the narrative below",
80
78
  )
81
79
 
82
- narrative = models.TextField(verbose_name="Narrative", blank=True, null=True)
80
+ narrative = models.TextField(verbose_name="Narrative", blank=True)
83
81
 
84
82
  class Meta:
85
83
  abstract = True
86
84
 
87
85
 
88
86
  class DeathReportTmgMethodsModelMixin(models.Model):
87
+ class Meta:
88
+ abstract = True
89
+
89
90
  def __str__(self):
90
91
  return str(self.death_report)
91
92
 
@@ -94,13 +95,10 @@ class DeathReportTmgMethodsModelMixin(models.Model):
94
95
  super().save(*args, **kwargs)
95
96
 
96
97
  def natural_key(self):
97
- return (self.action_identifier,) # noqa
98
+ return (self.action_identifier,)
98
99
 
99
100
  natural_key.dependencies = ["edc_adverse_event.causeofdeath"]
100
101
 
101
- class Meta:
102
- abstract = True
103
-
104
102
 
105
103
  class DeathReportTmgModelMixin(
106
104
  SiteModelMixin,
@@ -126,7 +124,7 @@ class DeathReportTmgModelMixin(
126
124
  verbose_name = "Death Report TMG (1st)"
127
125
  verbose_name_plural = "Death Report TMG (1st)"
128
126
  indexes = (
129
- NonUniqueSubjectIdentifierFieldMixin.Meta.indexes
130
- + ActionModelMixin.Meta.indexes
131
- + [models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])]
127
+ *NonUniqueSubjectIdentifierFieldMixin.Meta.indexes,
128
+ *ActionModelMixin.Meta.indexes,
129
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
132
130
  )
@@ -50,13 +50,14 @@ class SimpleDeathReportModelMixin(
50
50
 
51
51
  on_site = ActionIdentifierSiteManager()
52
52
 
53
- def natural_key(self):
54
- return (self.action_identifier,)
55
-
56
53
  class Meta(ActionModelMixin.Meta):
57
54
  abstract = True
58
55
  verbose_name = "Death Report"
59
56
  verbose_name_plural = "Death Reports"
60
- indexes = ActionModelMixin.Meta.indexes + [
61
- models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])
62
- ]
57
+ indexes = (
58
+ *ActionModelMixin.Meta.indexes,
59
+ models.Index(fields=["subject_identifier", "action_identifier", "site", "id"]),
60
+ )
61
+
62
+ def natural_key(self):
63
+ return (self.action_identifier,)
@@ -55,7 +55,6 @@ class HospitalizationModelMixin(NonUniqueSubjectIdentifierFieldMixin, models.Mod
55
55
  narrative = models.TextField(
56
56
  verbose_name="Narrative",
57
57
  max_length=500,
58
- null=True,
59
58
  blank=True,
60
59
  )
61
60
 
@@ -45,7 +45,7 @@ class AeFollowupModelAdminMixin(
45
45
  audit_fieldset_tuple,
46
46
  )
47
47
 
48
- radio_fields = {
48
+ radio_fields = { # noqa: RUF012
49
49
  "outcome": admin.VERTICAL,
50
50
  "followup": admin.VERTICAL,
51
51
  "ae_grade": admin.VERTICAL,
@@ -54,14 +54,12 @@ class AeFollowupModelAdminMixin(
54
54
  def get_search_fields(self, request) -> tuple[str, ...]:
55
55
  search_fields = super().get_search_fields(request)
56
56
  return tuple(
57
- set(
58
- search_fields
59
- + (
60
- "action_identifier",
61
- "ae_initial__subject_identifier",
62
- "ae_initial__action_identifier",
63
- )
64
- )
57
+ {
58
+ *search_fields,
59
+ "action_identifier",
60
+ "ae_initial__subject_identifier",
61
+ "ae_initial__action_identifier",
62
+ }
65
63
  )
66
64
 
67
65
  def get_list_display(self, request) -> tuple[str, ...]:
@@ -72,7 +70,7 @@ class AeFollowupModelAdminMixin(
72
70
  "description_column",
73
71
  "documents_column",
74
72
  )
75
- return custom_fields + tuple(f for f in list_display if f not in custom_fields)
73
+ return tuple({*list_display, *custom_fields})
76
74
 
77
75
  def get_list_filter(self, request) -> tuple[str, ...]:
78
76
  list_filter = super().get_list_filter(request)
@@ -83,7 +81,7 @@ class AeFollowupModelAdminMixin(
83
81
  "outcome",
84
82
  "report_datetime",
85
83
  )
86
- return custom_fields + tuple(f for f in list_filter if f not in custom_fields)
84
+ return tuple({*list_filter, *custom_fields})
87
85
 
88
86
  @display(description="Description", ordering="-report_datetime")
89
87
  def description_column(self, obj):
@@ -1,5 +1,3 @@
1
- from typing import Tuple
2
-
3
1
  from django.contrib import admin
4
2
  from django.contrib.admin import display
5
3
  from django.template.loader import render_to_string
@@ -90,8 +88,8 @@ class AeInitialModelAdminMixin(
90
88
  additional_instructions = format_html( # nosec B308, B703
91
89
  "Complete the initial AE report and forward to the TMG. "
92
90
  'Email to <a href="mailto:{}">{}</a>',
93
- mark_safe(email_contact), # nosec B308, B703
94
- mark_safe(email_contact), # nosec B308, B703
91
+ mark_safe(email_contact), # noqa: S308
92
+ mark_safe(email_contact), # noqa: S308
95
93
  )
96
94
 
97
95
  fieldsets = (
@@ -114,7 +112,7 @@ class AeInitialModelAdminMixin(
114
112
  "ae_classification_other",
115
113
  )
116
114
 
117
- def get_list_display(self, request) -> Tuple[str, ...]:
115
+ def get_list_display(self, request) -> tuple[str, ...]:
118
116
  list_display = super().get_list_display(request)
119
117
  custom_fields = (
120
118
  "subject_identifier_column",
@@ -125,7 +123,7 @@ class AeInitialModelAdminMixin(
125
123
  )
126
124
  return custom_fields + tuple(f for f in list_display if f not in custom_fields)
127
125
 
128
- def get_list_filter(self, request) -> Tuple[str, ...]:
126
+ def get_list_filter(self, request) -> tuple[str, ...]:
129
127
  list_filter = super().get_list_filter(request)
130
128
  custom_fields = (
131
129
  AeAwarenessListFilter,
@@ -65,7 +65,7 @@ class AdverseEventModelAdminMixin:
65
65
  """Returns formatted usernames and creation/modification dates."""
66
66
  return format_html(
67
67
  "{}",
68
- mark_safe(
68
+ mark_safe( # noqa: S308
69
69
  "<BR>".join(
70
70
  [
71
71
  obj.user_created,
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
4
  from datetime import date, datetime
5
- from typing import TYPE_CHECKING, Type
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  from django.conf import settings
8
8
  from django.urls import reverse
@@ -15,11 +15,11 @@ if TYPE_CHECKING:
15
15
 
16
16
  from .modeladmin_mixins import AdverseEventModelAdminMixin
17
17
 
18
- class ModelAdmin(AdverseEventModelAdminMixin, admin.ModelAdmin): ... # noqa
18
+ class ModelAdmin(AdverseEventModelAdminMixin, admin.ModelAdmin): ...
19
19
 
20
20
  class Model(BaseUuidModel):
21
21
  report_datetime: datetime
22
- ... # noqa
22
+ ...
23
23
 
24
24
 
25
25
  @dataclass(order=True)
@@ -34,7 +34,7 @@ class ColumnItem:
34
34
  date_field: str | None = field(default="report_datetime", compare=False)
35
35
  verbose_name: str = field(init=False, repr=False, compare=False)
36
36
  formatted_date: str = field(init=False, repr=False, compare=False)
37
- model_cls: Type[Model] = field(init=False, repr=False, compare=False)
37
+ model_cls: type[Model] = field(init=False, repr=False, compare=False)
38
38
  date_value: date = field(init=False, repr=False, compare=True)
39
39
 
40
40
  def __post_init__(self):
@@ -12,14 +12,8 @@ from ..utils import get_ae_model
12
12
 
13
13
 
14
14
  @receiver(m2m_changed, weak=False, dispatch_uid="update_ae_notifications_for_tmg_group")
15
- def update_ae_notifications_for_tmg_group(
16
- action, instance, reverse, model, pk_set, using, **kwargs
17
- ):
18
- try:
19
- instance.userprofile
20
- except AttributeError:
21
- pass
22
- else:
15
+ def update_ae_notifications_for_tmg_group(action, instance, **kwargs): # noqa: ARG001
16
+ if getattr(instance, "userprofile", None):
23
17
  try:
24
18
  tmg_ae_notification = Notification.objects.get(name=AE_TMG_ACTION)
25
19
  except ObjectDoesNotExist:
@@ -35,7 +29,7 @@ def update_ae_notifications_for_tmg_group(
35
29
 
36
30
 
37
31
  @receiver(post_save, weak=False, dispatch_uid="update_ae_initial_for_susar")
38
- def update_ae_initial_for_susar(sender, instance, raw, update_fields, **kwargs):
32
+ def update_ae_initial_for_susar(sender, instance, raw, update_fields, **kwargs): # noqa: ARG001
39
33
  if not raw and not update_fields:
40
34
  try:
41
35
  ae_susar_model_cls = get_ae_model("AeSusar")
@@ -61,7 +55,7 @@ def update_ae_initial_for_susar(sender, instance, raw, update_fields, **kwargs):
61
55
  weak=False,
62
56
  dispatch_uid="update_ae_initial_susar_reported",
63
57
  )
64
- def update_ae_initial_susar_reported(sender, instance, raw, update_fields, **kwargs):
58
+ def update_ae_initial_susar_reported(sender, instance, raw, update_fields, **kwargs): # noqa: ARG001
65
59
  if not raw and not update_fields:
66
60
  try:
67
61
  ae_initial_model_cls = get_ae_model("AeInitial")
@@ -83,7 +77,7 @@ def update_ae_initial_susar_reported(sender, instance, raw, update_fields, **kwa
83
77
 
84
78
 
85
79
  @receiver(post_delete, weak=False, dispatch_uid="post_delete_ae_susar")
86
- def post_delete_ae_susar(instance, **kwargs):
80
+ def post_delete_ae_susar(instance, **kwargs): # noqa: ARG001
87
81
  try:
88
82
  ae_susar_model_cls = get_ae_model("AeSusar")
89
83
  except LookupError:
@@ -99,14 +93,8 @@ def post_delete_ae_susar(instance, **kwargs):
99
93
 
100
94
 
101
95
  @receiver(m2m_changed, weak=False, dispatch_uid="update_death_notifications_for_tmg_group")
102
- def update_death_notifications_for_tmg_group(
103
- action, instance, reverse, model, pk_set, using, **kwargs
104
- ):
105
- try:
106
- instance.userprofile
107
- except AttributeError:
108
- pass
109
- else:
96
+ def update_death_notifications_for_tmg_group(action, instance, **kwargs): # noqa: ARG001
97
+ if getattr(instance, "userprofile", None):
110
98
  try:
111
99
  tmg_death_notification = Notification.objects.get(name=DEATH_REPORT_TMG_ACTION)
112
100
  except ObjectDoesNotExist:
@@ -95,16 +95,15 @@ class DeathPdfReport(CrfPdfReport):
95
95
  row = ["Main cause of death:"]
96
96
  if not self.model_obj.cause_of_death:
97
97
  row.append(self.not_reported_text)
98
- else:
99
- if self.cause_of_death == OTHER:
100
- row.append(
101
- fill(
102
- f"{self.cause_of_death}: " f"{self.cause_of_death_other}",
103
- width=80,
104
- )
98
+ elif self.cause_of_death == OTHER:
99
+ row.append(
100
+ fill(
101
+ f"{self.cause_of_death}: {self.cause_of_death_other}",
102
+ width=80,
105
103
  )
106
- else:
107
- row.append(fill(self.cause_of_death))
104
+ )
105
+ else:
106
+ row.append(fill(self.cause_of_death))
108
107
  rows.append(row)
109
108
 
110
109
  t = Table(rows, (4 * cm, 14 * cm))
@@ -42,15 +42,15 @@ if TYPE_CHECKING:
42
42
  DeathReportTmgModelMixin,
43
43
  )
44
44
 
45
- class DeathReportTmgModel(DeathReportTmgModelMixin, BaseUuidModel): ... # noqa
45
+ class DeathReportTmgModel(DeathReportTmgModelMixin, BaseUuidModel): ...
46
46
 
47
- class DeathReportTmgSecondModel(DeathReportTmgModelMixin, BaseUuidModel): ... # noqa
47
+ class DeathReportTmgSecondModel(DeathReportTmgModelMixin, BaseUuidModel): ...
48
48
 
49
- class AeInitialModel(AeInitialModelMixin, BaseUuidModel): ... # noqa
49
+ class AeInitialModel(AeInitialModelMixin, BaseUuidModel): ...
50
50
 
51
- class AeFollowupModel(AeFollowupModelMixin, BaseUuidModel): ... # noqa
51
+ class AeFollowupModel(AeFollowupModelMixin, BaseUuidModel): ...
52
52
 
53
- class DeathReportModel(DeathReportModelMixin, BaseUuidModel): ... # noqa
53
+ class DeathReportModel(DeathReportModelMixin, BaseUuidModel): ...
54
54
 
55
55
 
56
56
  register = template.Library()
@@ -89,17 +89,13 @@ def format_ae_description(context, ae_initial, wrap_length):
89
89
  try:
90
90
  context["sae_reason"] = format_html(
91
91
  "{}",
92
- mark_safe(
93
- wrapx(escape_braces(ae_initial.sae_reason.name), wrap_length)
94
- ), # nosec B703, B308
92
+ mark_safe(wrapx(escape_braces(ae_initial.sae_reason.name), wrap_length)), # nosec B703, B308
95
93
  )
96
94
  except AttributeError:
97
95
  context["sae_reason"] = ""
98
96
  context["ae_description"] = format_html(
99
97
  "{}",
100
- mark_safe(
101
- wrapx(escape_braces(ae_initial.ae_description), wrap_length)
102
- ), # nosec B703, B308
98
+ mark_safe(wrapx(escape_braces(ae_initial.ae_description), wrap_length)), # nosec B703, B308
103
99
  )
104
100
  return context
105
101
 
@@ -124,15 +120,11 @@ def format_ae_followup_description(context, ae_followup, wrap_length):
124
120
  context["sae_reason"] = ""
125
121
  context["relevant_history"] = format_html(
126
122
  "{}",
127
- mark_safe(
128
- wrapx(escape_braces(ae_followup.relevant_history), wrap_length)
129
- ), # nosec B703, B308
123
+ mark_safe(wrapx(escape_braces(ae_followup.relevant_history), wrap_length)), # nosec B703, B308
130
124
  )
131
125
  context["ae_description"] = format_html(
132
126
  "{}",
133
- mark_safe(
134
- wrapx(escape_braces(ae_followup.ae_initial.ae_description), wrap_length)
135
- ), # nosec B703, B308
127
+ mark_safe(wrapx(escape_braces(ae_followup.ae_initial.ae_description), wrap_length)), # nosec B703, B308
136
128
  )
137
129
  return context
138
130
 
@@ -158,9 +150,7 @@ def format_ae_susar_description(context, ae_susar, wrap_length):
158
150
  )
159
151
  context["ae_description"] = format_html(
160
152
  "{}",
161
- mark_safe(
162
- wrapx(escape_braces(ae_susar.ae_initial.ae_description), wrap_length)
163
- ), # nosec B703, B308
153
+ mark_safe(wrapx(escape_braces(ae_susar.ae_initial.ae_description), wrap_length)), # nosec B703, B308
164
154
  )
165
155
  return context
166
156
 
edc_adverse_event/urls.py CHANGED
@@ -3,11 +3,15 @@ from django.urls.conf import path
3
3
  from edc_protocol.research_protocol_config import ResearchProtocolConfig
4
4
 
5
5
  from .admin_site import edc_adverse_event_admin
6
- from .views import AeHomeView, ClosedTmgAeListboardView
6
+ from .views import (
7
+ AeHomeView,
8
+ ClosedTmgAeListboardView,
9
+ NewTmgAeListboardView,
10
+ OpenTmgAeListboardView,
11
+ TmgHomeView,
12
+ )
7
13
  from .views import DeathListboardView as TmgDeathListboardView
8
- from .views import NewTmgAeListboardView, OpenTmgAeListboardView
9
14
  from .views import SummaryListboardView as TmgSummaryListboardView
10
- from .views import TmgHomeView
11
15
 
12
16
  app_name = "edc_adverse_event"
13
17
 
@@ -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 forms
6
6
  from django.apps import apps as django_apps
@@ -71,7 +71,7 @@ def get_hospitalization_model_app_label() -> str:
71
71
 
72
72
  def get_ae_model(
73
73
  model_name,
74
- ) -> Type[DeathReportModelMixin] | Type[AeInitialModelMixin] | Type[AeFollowupModelMixin]:
74
+ ) -> type[DeathReportModelMixin] | type[AeInitialModelMixin] | type[AeFollowupModelMixin]:
75
75
  return django_apps.get_model(f"{get_adverse_event_app_label()}.{model_name}")
76
76
 
77
77
 
@@ -17,13 +17,13 @@ if TYPE_CHECKING:
17
17
  )
18
18
  from edc_model.models import BaseUuidModel
19
19
 
20
- class AeInitialModel(AeInitialModelMixin, BaseUuidModel): ... # noqa
20
+ class AeInitialModel(AeInitialModelMixin, BaseUuidModel): ...
21
21
 
22
- class AeFollowupModel(AeFollowupModelMixin, BaseUuidModel): ... # noqa
22
+ class AeFollowupModel(AeFollowupModelMixin, BaseUuidModel): ...
23
23
 
24
- class DeathReportTmgModel(DeathReportTmgModelMixin, BaseUuidModel): ... # noqa
24
+ class DeathReportTmgModel(DeathReportTmgModelMixin, BaseUuidModel): ...
25
25
 
26
- class DeathReportModel(DeathReportModelMixin, BaseUuidModel): ... # noqa
26
+ class DeathReportModel(DeathReportModelMixin, BaseUuidModel): ...
27
27
 
28
28
 
29
29
  @dataclass
@@ -21,7 +21,7 @@ def check_for_edc_appconfig(app_configs, **kwargs) -> list[CheckMessage]:
21
21
  id="edc_appconfig.E001",
22
22
  )
23
23
  )
24
- if "edc_appconfig.apps.AppConfig" != settings.INSTALLED_APPS[-1:][0]:
24
+ if settings.INSTALLED_APPS[-1:][0] != "edc_appconfig.apps.AppConfig":
25
25
  errors.append(
26
26
  Error(
27
27
  "edc_appconfig should be the last app in INSTALLED_APPS. "
@@ -25,18 +25,17 @@ class AppointmentStatusUpdater:
25
25
  raise AppointmentStatusUpdaterError(
26
26
  f"Not an Appointment model instance. Got {self.appointment._meta.label_lower}."
27
27
  )
28
- else:
29
- if not getattr(self.appointment, "id", None):
30
- raise AppointmentStatusUpdaterError(
31
- "Appointment instance must exist. Got `id` is None"
32
- )
33
- if change_to_in_progress and self.appointment.appt_status != IN_PROGRESS_APPT:
34
- self.appointment.appt_status = IN_PROGRESS_APPT
35
- self.appointment.save_base(update_fields=["appt_status"])
36
- if clear_others_in_progress:
37
- for appointment in self.appointment.__class__.objects.filter(
38
- visit_schedule_name=self.appointment.visit_schedule_name,
39
- schedule_name=self.appointment.schedule_name,
40
- appt_status=IN_PROGRESS_APPT,
41
- ).exclude(id=self.appointment.id):
42
- update_appt_status(appointment, save=True)
28
+ if not getattr(self.appointment, "id", None):
29
+ raise AppointmentStatusUpdaterError(
30
+ "Appointment instance must exist. Got `id` is None"
31
+ )
32
+ if change_to_in_progress and self.appointment.appt_status != IN_PROGRESS_APPT:
33
+ self.appointment.appt_status = IN_PROGRESS_APPT
34
+ self.appointment.save_base(update_fields=["appt_status"])
35
+ if clear_others_in_progress:
36
+ for appointment in self.appointment.__class__.objects.filter(
37
+ visit_schedule_name=self.appointment.visit_schedule_name,
38
+ schedule_name=self.appointment.schedule_name,
39
+ appt_status=IN_PROGRESS_APPT,
40
+ ).exclude(id=self.appointment.id):
41
+ update_appt_status(appointment, save=True)