meta-edc 0.3.39__py3-none-any.whl → 1.4.0__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.
Files changed (637) hide show
  1. meta_ae/action_items.py +38 -27
  2. meta_ae/admin/__init__.py +11 -0
  3. meta_ae/admin/ae_initial_admin.py +5 -2
  4. meta_ae/admin/ae_susar_admin.py +1 -1
  5. meta_ae/admin/death_report_admin.py +1 -1
  6. meta_ae/admin/modeladmin_mixins.py +14 -15
  7. meta_ae/baker_recipes.py +4 -6
  8. meta_ae/choices.py +1 -1
  9. meta_ae/forms/__init__.py +13 -0
  10. meta_ae/forms/death_report_form.py +1 -1
  11. meta_ae/forms/modelform_mixins.py +2 -2
  12. meta_ae/list_data.py +1 -1
  13. meta_ae/migrations/0001_initial.py +27 -27
  14. meta_ae/migrations/0006_aelocalreview_aesponsorreview.py +5 -5
  15. meta_ae/migrations/0017_auto_20221130_2257.py +1 -1
  16. meta_ae/migrations/0022_historicalhospitalization_hospitalization.py +5 -13
  17. meta_ae/migrations/0023_alter_aefollowup_action_identifier_and_more.py +2017 -0
  18. meta_ae/model_mixins/__init__.py +2 -0
  19. meta_ae/model_mixins/ae_review_model_mixin.py +6 -6
  20. meta_ae/model_mixins/death_report_model_mixin.py +3 -3
  21. meta_ae/models/__init__.py +13 -0
  22. meta_ae/models/hospitalization.py +3 -3
  23. meta_ae/pdf_reports/__init__.py +2 -0
  24. meta_ae/templatetags/meta_ae_extras.py +4 -6
  25. meta_analytics/.DS_Store +0 -0
  26. meta_analytics/README.rst +1 -2
  27. meta_analytics/dataframes/__init__.py +27 -0
  28. meta_analytics/dataframes/constants.py +5 -2
  29. meta_analytics/dataframes/get_eos_df.py +16 -4
  30. meta_analytics/dataframes/get_glucose_df.py +166 -0
  31. meta_analytics/dataframes/get_glucose_fbg_df.py +26 -0
  32. meta_analytics/dataframes/get_glucose_fbg_ogtt_df.py +21 -0
  33. meta_analytics/dataframes/get_last_imp_visits_df.py +12 -10
  34. meta_analytics/dataframes/glucose_endpoints/__init__.py +2 -0
  35. meta_analytics/dataframes/glucose_endpoints/endpoint_by_date.py +125 -124
  36. meta_analytics/dataframes/glucose_endpoints/glucose_endpoints_by_date.py +111 -235
  37. meta_analytics/dataframes/screening/__init__.py +2 -0
  38. meta_analytics/dataframes/screening/get_glucose_tested_only_df.py +1 -2
  39. meta_analytics/dataframes/screening/get_screening_df.py +9 -15
  40. meta_analytics/dataframes/utils.py +21 -12
  41. meta_analytics/get_tables.py +1 -2
  42. meta_analytics/tables/__init__.py +2 -0
  43. meta_analytics/tables/enrolled/glucose.py +2 -1
  44. meta_analytics/utils.py +81 -0
  45. meta_auth/auths.py +1 -1
  46. meta_consent/action_items.py +22 -3
  47. meta_consent/admin/__init__.py +7 -0
  48. meta_consent/admin/actions/__init__.py +2 -0
  49. meta_consent/admin/actions/create_missing_prescriptions.py +2 -2
  50. meta_consent/admin/list_filters.py +22 -0
  51. meta_consent/admin/modeladmin_mixins.py +4 -5
  52. meta_consent/admin/subject_consent_v1_ext_admin.py +93 -0
  53. meta_consent/baker_recipes.py +7 -7
  54. meta_consent/consents.py +15 -2
  55. meta_consent/constants.py +1 -0
  56. meta_consent/form_validators/__init__.py +2 -0
  57. meta_consent/forms/__init__.py +8 -0
  58. meta_consent/forms/subject_consent_v1_ext_form.py +47 -0
  59. meta_consent/forms/subject_reconsent_form.py +4 -4
  60. meta_consent/management/commands/create_missing_prescriptions.py +5 -3
  61. meta_consent/migrations/0001_initial.py +9 -9
  62. meta_consent/migrations/0024_historicalsubjectconsentv1.py +3 -8
  63. meta_consent/migrations/0026_historicalsubjectconsentv1ext_subjectconsentv1ext.py +535 -0
  64. meta_consent/migrations/0027_auto_20250111_0344.py +30 -0
  65. meta_consent/migrations/0028_historicalsubjectconsentv1ext_assessment_score_and_more.py +162 -0
  66. meta_consent/migrations/0029_alter_historicalsubjectconsentv1ext_agrees_to_extension_and_more.py +33 -0
  67. meta_consent/migrations/0030_auto_20250120_2114.py +40 -0
  68. meta_consent/migrations/0031_alter_historicalsubjectconsent_guardian_name_and_more.py +124 -0
  69. meta_consent/migrations/0032_alter_historicalsubjectconsent_device_created_and_more.py +678 -0
  70. meta_consent/migrations/0033_historicalsubjectconsentspfq_subjectconsentspfq.py +615 -0
  71. meta_consent/migrations/0034_remove_subjectconsentspfq_site_and_more.py +23 -0
  72. meta_consent/migrations/0035_alter_historicalsubjectconsent_consent_definition_name_and_more.py +43 -0
  73. meta_consent/models/__init__.py +10 -0
  74. meta_consent/models/model_mixins.py +1 -2
  75. meta_consent/models/signals.py +25 -11
  76. meta_consent/models/subject_consent.py +2 -2
  77. meta_consent/models/subject_consent_v1.py +0 -1
  78. meta_consent/models/subject_consent_v1_ext.py +34 -0
  79. meta_consent/models/subject_reconsent.py +4 -4
  80. meta_dashboard/navbars.py +2 -6
  81. meta_dashboard/patterns.py +1 -1
  82. meta_dashboard/templates/meta_dashboard/{bootstrap3/buttons → buttons}/eligibility_button.html +1 -1
  83. meta_dashboard/templates/meta_dashboard/{bootstrap3/buttons → buttons}/screening_button.html +1 -1
  84. meta_dashboard/templates/meta_dashboard/subject/dashboard/sidebar.html +24 -0
  85. meta_dashboard/templates/meta_dashboard/{bootstrap3/subject → subject}/dashboard/top_bar.html +1 -1
  86. meta_dashboard/templates/meta_dashboard/subject/dashboard.html +14 -0
  87. meta_dashboard/templatetags/meta_dashboard_extras.py +9 -14
  88. meta_dashboard/urls.py +5 -5
  89. meta_dashboard/view_utils/__init__.py +13 -0
  90. meta_dashboard/view_utils/subject_screening_button.py +13 -20
  91. meta_dashboard/views/__init__.py +8 -0
  92. meta_dashboard/views/ae/__init__.py +2 -0
  93. meta_dashboard/views/ae/ae_listboard_view.py +1 -1
  94. meta_dashboard/views/ae/death_report_listboard_view.py +1 -1
  95. meta_dashboard/views/screening/__init__.py +2 -0
  96. meta_dashboard/views/screening/listboard_view.py +2 -3
  97. meta_dashboard/views/subject/__init__.py +2 -0
  98. meta_dashboard/views/subject/dashboard/__init__.py +2 -0
  99. meta_dashboard/views/subject/dashboard/dashboard_view.py +19 -8
  100. meta_dashboard/views/subject/listboard/__init__.py +2 -0
  101. meta_dashboard/views/subject/listboard/listboard_view.py +2 -3
  102. meta_edc/__init__.py +5 -9
  103. meta_edc/admin.py +3 -4
  104. meta_edc/celery.py +2 -2
  105. meta_edc/celery_live.py +19 -0
  106. meta_edc/celery_uat.py +25 -0
  107. meta_edc/management/commands/update_forms_reference.py +16 -14
  108. meta_edc/meta_version.py +2 -2
  109. meta_edc/navbars.py +7 -5
  110. meta_edc/settings/debug.py +13 -4
  111. meta_edc/settings/defaults.py +55 -18
  112. meta_edc/settings/live.py +4 -1
  113. meta_edc/settings/logging.py +9 -4
  114. meta_edc/settings/minimal.py +4 -5
  115. meta_edc/settings/uat.py +3 -1
  116. meta_edc/templates/meta_edc/{bootstrap3/base.html → base.html} +1 -1
  117. meta_edc/templates/meta_edc/{bootstrap3/home.html → home.html} +2 -2
  118. meta_edc/urls.py +3 -1
  119. meta_edc/utils.py +3 -1
  120. meta_edc/views/__init__.py +2 -0
  121. meta_edc/views/home_view.py +1 -2
  122. meta_edc-1.4.0.dist-info/METADATA +174 -0
  123. {meta_edc-0.3.39.dist-info → meta_edc-1.4.0.dist-info}/RECORD +578 -586
  124. meta_edc-1.4.0.dist-info/WHEEL +4 -0
  125. meta_labs/list_data.py +2 -2
  126. meta_labs/reportables.py +80 -11
  127. meta_lists/list_data.py +13 -4
  128. meta_lists/migrations/0008_auto_20200528_1517.py +2 -2
  129. meta_lists/migrations/0019_auto_20250128_0143.py +48 -0
  130. meta_lists/migrations/0020_alter_abnormalfootappearanceobservations_extra_value_and_more.py +404 -0
  131. meta_pharmacy/admin/__init__.py +5 -0
  132. meta_pharmacy/admin/rx_admin.py +1 -0
  133. meta_pharmacy/admin/substitutions_admin.py +3 -3
  134. meta_pharmacy/constants.py +1 -1
  135. meta_pharmacy/forms/__init__.py +2 -0
  136. meta_pharmacy/forms/rx_form.py +0 -1
  137. meta_pharmacy/forms/substitutions_form.py +6 -4
  138. meta_pharmacy/labels/__init__.py +5 -2
  139. meta_pharmacy/labels/draw_label_for_subject_with_barcode.py +4 -1
  140. meta_pharmacy/labels/draw_label_with_test_data.py +2 -2
  141. meta_pharmacy/labels/label_data.py +1 -2
  142. meta_pharmacy/labels/print_sheets.py +4 -6
  143. meta_pharmacy/management/commands/update_initial_pharmacy_data.py +4 -3
  144. meta_pharmacy/migrations/0002_initial.py +7 -20
  145. meta_pharmacy/migrations/0003_auto_20240909_2335.py +3 -2
  146. meta_pharmacy/migrations/0006_lotnumber_label.py +5 -14
  147. meta_pharmacy/migrations/0008_remove_lotnumber_medication_and_more.py +5 -6
  148. meta_pharmacy/migrations/0010_alter_historicallabeldata_device_created_and_more.py +382 -0
  149. meta_pharmacy/models/__init__.py +7 -0
  150. meta_pharmacy/models/label_data.py +4 -5
  151. meta_pharmacy/models/rx_label.py +0 -1
  152. meta_pharmacy/models/substitutions.py +4 -4
  153. meta_pharmacy/prepare_meta_pharmacy.py +1 -1
  154. meta_pharmacy/utils/__init__.py +2 -0
  155. meta_pharmacy/utils/update_initial_pharmacy_data.py +1 -1
  156. meta_prn/action_items.py +44 -45
  157. meta_prn/admin/__init__.py +16 -0
  158. meta_prn/admin/dm_referral_admin.py +2 -1
  159. meta_prn/admin/end_of_study_admin.py +26 -15
  160. meta_prn/admin/loss_to_followup_admin.py +3 -2
  161. meta_prn/admin/off_study_medication_admin.py +5 -6
  162. meta_prn/admin/offschedule_admin.py +12 -11
  163. meta_prn/admin/offschedule_dm_referral_admin.py +11 -10
  164. meta_prn/admin/offschedule_postnatal_admin.py +15 -7
  165. meta_prn/admin/offschedule_pregnancy_admin.py +18 -9
  166. meta_prn/admin/onschedule_admin.py +7 -8
  167. meta_prn/admin/onschedule_dm_referral_admin.py +11 -12
  168. meta_prn/admin/pregnancy_notification_admin.py +5 -6
  169. meta_prn/admin/protocol_incident_admin.py +1 -1
  170. meta_prn/admin/subject_transfer_admin.py +1 -1
  171. meta_prn/baker_recipes.py +10 -10
  172. meta_prn/choices.py +11 -7
  173. meta_prn/constants.py +1 -0
  174. meta_prn/form_validators/__init__.py +5 -0
  175. meta_prn/form_validators/end_of_study.py +65 -20
  176. meta_prn/form_validators/protocol_incident.py +1 -1
  177. meta_prn/forms/__init__.py +13 -0
  178. meta_prn/forms/dm_referral_form.py +2 -8
  179. meta_prn/forms/end_of_study_form.py +1 -1
  180. meta_prn/forms/loss_to_followup_form.py +1 -1
  181. meta_prn/forms/off_study_medication_form.py +2 -2
  182. meta_prn/forms/offschedule_form.py +25 -0
  183. meta_prn/forms/pregnancy_notification_form.py +15 -17
  184. meta_prn/list_data.py +3 -3
  185. meta_prn/migrations/0001_initial.py +25 -25
  186. meta_prn/migrations/0017_auto_20220307_1929.py +5 -5
  187. meta_prn/migrations/0018_auto_20220309_2106.py +9 -9
  188. meta_prn/migrations/0021_auto_20220316_2147.py +13 -13
  189. meta_prn/migrations/0022_auto_20220318_0133.py +9 -9
  190. meta_prn/migrations/0032_historicalegfrnotification_egfrnotification.py +5 -13
  191. meta_prn/migrations/0034_auto_20220630_1110.py +1 -1
  192. meta_prn/migrations/0035_auto_20220630_1140.py +1 -1
  193. meta_prn/migrations/0038_alter_endofstudy_delivery_date_and_more.py +5 -13
  194. meta_prn/migrations/0041_endofstudy_transfer_date_and_more.py +5 -13
  195. meta_prn/migrations/0057_historicalonscheduledmreferral_and_more.py +13 -38
  196. meta_prn/migrations/0060_alter_onschedule_managers_and_more.py +55 -0
  197. meta_prn/migrations/0061_auto_20250115_2025.py +56 -0
  198. meta_prn/migrations/0062_alter_endofstudy_offstudy_reason_and_more.py +72 -0
  199. meta_prn/migrations/0063_historicaloffstudymedication_singleton_field_and_more.py +37 -0
  200. meta_prn/migrations/0064_auto_20250602_2143.py +18 -0
  201. meta_prn/migrations/0065_alter_historicaloffstudymedication_subject_identifier_and_more.py +23 -0
  202. meta_prn/migrations/0066_alter_historicallosstofollowup_subject_identifier_and_more.py +23 -0
  203. meta_prn/migrations/0067_alter_offschedule_managers_and_more.py +2557 -0
  204. meta_prn/migrations/0068_alter_dmreferral_referral_note_and_more.py +235 -0
  205. meta_prn/migrations/0069_alter_historicaloffstudymedication_singleton_field_and_more.py +37 -0
  206. meta_prn/models/__init__.py +20 -0
  207. meta_prn/models/dm_referral.py +2 -2
  208. meta_prn/models/end_of_study.py +28 -23
  209. meta_prn/models/loss_to_followup.py +8 -10
  210. meta_prn/models/off_study_medication.py +7 -4
  211. meta_prn/models/offschedule.py +4 -4
  212. meta_prn/models/pregnancy_notification.py +3 -5
  213. meta_prn/models/protocol_incident.py +5 -2
  214. meta_prn/models/signals.py +16 -14
  215. meta_prn/models/subject_transfer.py +7 -0
  216. meta_prn/templates/meta_prn/eos/additional_instructions.html +3 -0
  217. meta_prn/templates/meta_prn/offschedule/additional_instructions.html +2 -0
  218. meta_rando/migrations/0001_initial.py +5 -5
  219. meta_rando/migrations/0006_alter_historicalrandomizationlist_allocated_user_and_more.py +130 -0
  220. meta_rando/migrations/0007_spfqlist.py +197 -0
  221. meta_rando/migrations/0008_delete_spfqlist.py +16 -0
  222. meta_rando/models/__init__.py +1 -0
  223. meta_rando/{models.py → models/randomization_list.py} +3 -3
  224. meta_rando/randomizers.py +2 -2
  225. meta_reports/__init__.py +2 -0
  226. meta_reports/admin/__init__.py +16 -0
  227. meta_reports/admin/dbviews/__init__.py +13 -0
  228. meta_reports/admin/dbviews/glucose_summary_admin.py +7 -7
  229. meta_reports/admin/dbviews/imp_substitutions_admin.py +14 -13
  230. meta_reports/admin/dbviews/missing_screening_ogtt_admin/__init__.py +5 -0
  231. meta_reports/admin/dbviews/missing_screening_ogtt_admin/note_model_admin.py +27 -3
  232. meta_reports/admin/dbviews/missing_screening_ogtt_admin/unmanaged_model_admin.py +7 -7
  233. meta_reports/admin/dbviews/on_study_missing_lab_values_admin/__init__.py +2 -0
  234. meta_reports/admin/dbviews/on_study_missing_lab_values_admin/unmanaged_model_admin.py +0 -3
  235. meta_reports/admin/dbviews/on_study_missing_values_admin/__init__.py +2 -0
  236. meta_reports/admin/dbviews/on_study_missing_values_admin/unmanaged_model_admin.py +0 -1
  237. meta_reports/admin/dbviews/patient_history_missing_baseline_cd4_admin.py +9 -9
  238. meta_reports/admin/dbviews/unattended_three_in_row2_admin.py +6 -6
  239. meta_reports/admin/dbviews/unattended_three_in_row_admin.py +5 -5
  240. meta_reports/admin/dbviews/unattended_two_in_row_admin.py +5 -5
  241. meta_reports/admin/endpoints_admin.py +1 -1
  242. meta_reports/admin/endpoints_all_admin.py +0 -1
  243. meta_reports/admin/last_imp_refill_admin.py +33 -36
  244. meta_reports/admin/list_filters.py +3 -3
  245. meta_reports/admin/modeladmin_mixins.py +10 -17
  246. meta_reports/death_report.py +2 -2
  247. meta_reports/forms/__init__.py +2 -0
  248. meta_reports/forms/missing_ogtt_note_form.py +3 -4
  249. meta_reports/management/commands/generate_endpoints.py +5 -4
  250. meta_reports/migrations/0035_historicalmissingogttnote_missingogttnote.py +5 -14
  251. meta_reports/migrations/0054_auto_20250422_2003.py +81 -0
  252. meta_reports/migrations/0055_alter_glucosesummary_table.py +17 -0
  253. meta_reports/migrations/0056_auto_20250422_2214.py +54 -0
  254. meta_reports/migrations/0057_auto_20250422_2224.py +54 -0
  255. meta_reports/migrations/0058_auto_20250422_2232.py +54 -0
  256. meta_reports/migrations/0059_alter_endpoints_created_and_more.py +161 -0
  257. meta_reports/migrations/0060_auto_20250926_0242.py +366 -0
  258. meta_reports/migrations/0061_auto_20251004_0043.py +21 -0
  259. meta_reports/migrations/0062_auto_20251004_0106.py +21 -0
  260. meta_reports/models/__init__.py +17 -0
  261. meta_reports/models/dbviews/__init__.py +14 -0
  262. meta_reports/models/dbviews/glucose_summary/__init__.py +2 -0
  263. meta_reports/models/dbviews/glucose_summary/unmanaged_model.py +15 -3
  264. meta_reports/models/dbviews/glucose_summary/view_definition.py +8 -5
  265. meta_reports/models/dbviews/imp_substitutions/__init__.py +2 -0
  266. meta_reports/models/dbviews/imp_substitutions/unmanaged_model.py +1 -2
  267. meta_reports/models/dbviews/imp_substitutions/view_definition.py +1 -1
  268. meta_reports/models/dbviews/missing_screening_ogtt/__init__.py +2 -0
  269. meta_reports/models/dbviews/missing_screening_ogtt/note_model.py +2 -2
  270. meta_reports/models/dbviews/missing_screening_ogtt/unmanaged_model.py +4 -3
  271. meta_reports/models/dbviews/on_study_missing_lab_values/__init__.py +2 -0
  272. meta_reports/models/dbviews/on_study_missing_lab_values/qa_cases.py +13 -11
  273. meta_reports/models/dbviews/on_study_missing_lab_values/unmanged_model.py +0 -1
  274. meta_reports/models/dbviews/on_study_missing_values/__init__.py +2 -0
  275. meta_reports/models/dbviews/on_study_missing_values/qa_cases.py +19 -1
  276. meta_reports/models/dbviews/on_study_missing_values/unmanged_model.py +0 -1
  277. meta_reports/models/dbviews/patient_history_missing_baseline_cd4/__init__.py +2 -0
  278. meta_reports/models/dbviews/patient_history_missing_baseline_cd4/unmanaged_model.py +0 -1
  279. meta_reports/models/dbviews/unattended_three_in_row/__init__.py +2 -0
  280. meta_reports/models/dbviews/unattended_three_in_row/unmanaged_model.py +0 -1
  281. meta_reports/models/dbviews/unattended_three_in_row2/__init__.py +2 -0
  282. meta_reports/models/dbviews/unattended_three_in_row2/unmanaged_model.py +0 -1
  283. meta_reports/models/dbviews/unattended_two_in_row/__init__.py +2 -0
  284. meta_reports/models/dbviews/unattended_two_in_row/unmanaged_model.py +0 -1
  285. meta_reports/models/endpoints.py +8 -4
  286. meta_reports/models/last_imp_refill.py +2 -3
  287. meta_reports/pdf_report.py +2 -2
  288. meta_reports/tasks.py +4 -3
  289. meta_reports/templates/meta_reports/columns/subject_identifier_column.html +1 -1
  290. meta_reports/templates/meta_reports/endpoints_all_change_list_note.html +1 -1
  291. meta_reports/templates/meta_reports/endpoints_change_list_note.html +1 -1
  292. meta_reports/templates/meta_reports/last_imp_refill/changelist_note.html +13 -0
  293. meta_screening/admin/__init__.py +8 -0
  294. meta_screening/admin/fieldsets.py +13 -15
  295. meta_screening/admin/list_filters.py +7 -5
  296. meta_screening/admin/screening_part_one_admin.py +1 -3
  297. meta_screening/admin/screening_part_three_admin.py +2 -3
  298. meta_screening/admin/screening_part_two_admin.py +7 -10
  299. meta_screening/admin/subject_refusal_admin.py +5 -3
  300. meta_screening/admin/subject_screening_admin.py +21 -10
  301. meta_screening/baker_recipes.py +18 -10
  302. meta_screening/calculators.py +1 -1
  303. meta_screening/choices.py +1 -1
  304. meta_screening/constants.py +1 -1
  305. meta_screening/eligibility/__init__.py +9 -0
  306. meta_screening/eligibility/eligibility.py +21 -14
  307. meta_screening/eligibility/eligibility_part_one.py +1 -1
  308. meta_screening/eligibility/eligibility_part_three/__init__.py +2 -0
  309. meta_screening/eligibility/eligibility_part_three/base_eligibility_part_three.py +68 -49
  310. meta_screening/eligibility/eligibility_part_three/eligibility_part_three_phase_three.py +14 -15
  311. meta_screening/eligibility/eligibility_part_two.py +1 -1
  312. meta_screening/form_validators/__init__.py +8 -0
  313. meta_screening/form_validators/screening_part_one.py +1 -1
  314. meta_screening/form_validators/screening_part_three.py +6 -2
  315. meta_screening/form_validators/screening_part_two.py +1 -1
  316. meta_screening/form_validators/subject_refusal.py +1 -1
  317. meta_screening/forms/__init__.py +20 -0
  318. meta_screening/forms/field_lists.py +16 -18
  319. meta_screening/forms/screening_part_one_form.py +2 -2
  320. meta_screening/forms/screening_part_three_form.py +5 -3
  321. meta_screening/forms/screening_part_two_form.py +1 -5
  322. meta_screening/forms/subject_refusal_form.py +0 -4
  323. meta_screening/forms/subject_screening_form.py +0 -4
  324. meta_screening/migrations/0001_initial.py +15 -15
  325. meta_screening/migrations/0010_auto_20191106_0828.py +5 -5
  326. meta_screening/migrations/0012_auto_20191107_0427.py +1 -1
  327. meta_screening/migrations/0068_alter_historicalscreeningpartone_acute_condition_and_more.py +1579 -0
  328. meta_screening/model_mixins/__init__.py +8 -0
  329. meta_screening/model_mixins/calculated_model_mixin.py +2 -2
  330. meta_screening/model_mixins/creatinine_fields_model_mixin.py +1 -1
  331. meta_screening/model_mixins/eligibility_model_mixin.py +6 -4
  332. meta_screening/model_mixins/part_one_fields_model_mixin.py +16 -19
  333. meta_screening/model_mixins/part_three_fields_model_mixin.py +6 -7
  334. meta_screening/model_mixins/part_two_fields_model_mixin.py +19 -17
  335. meta_screening/models/__init__.py +9 -0
  336. meta_screening/models/icp_referral.py +5 -5
  337. meta_screening/models/proxy_models.py +1 -1
  338. meta_screening/models/signals.py +10 -11
  339. meta_screening/models/subject_refusal.py +1 -1
  340. meta_screening/models/subject_screening.py +2 -4
  341. meta_subject/action_items.py +18 -14
  342. meta_subject/admin/__init__.py +42 -0
  343. meta_subject/admin/birth_outcome_admin.py +7 -9
  344. meta_subject/admin/blood_results/__init__.py +9 -0
  345. meta_subject/admin/blood_results/blood_results_fbc_admin.py +1 -1
  346. meta_subject/admin/blood_results/blood_results_hba1c_admin.py +1 -1
  347. meta_subject/admin/blood_results/blood_results_ins_admin.py +1 -1
  348. meta_subject/admin/blood_results/blood_results_lft_admin.py +1 -1
  349. meta_subject/admin/blood_results/blood_results_lipids_admin.py +1 -1
  350. meta_subject/admin/blood_results/blood_results_rft_admin.py +3 -5
  351. meta_subject/admin/complications_glycemia_admin.py +1 -1
  352. meta_subject/admin/delivery_admin.py +8 -11
  353. meta_subject/admin/diabetes/__init__.py +2 -0
  354. meta_subject/admin/diabetes/dm_endpoint_admin.py +2 -2
  355. meta_subject/admin/diabetes/dm_followup_admin.py +3 -2
  356. meta_subject/admin/egfr_drop_notification_admin.py +1 -1
  357. meta_subject/admin/fields.py +5 -5
  358. meta_subject/admin/fieldsets.py +5 -5
  359. meta_subject/admin/followup_examination_admin.py +11 -9
  360. meta_subject/admin/followup_vitals_admin.py +31 -6
  361. meta_subject/admin/glucose_admin.py +4 -8
  362. meta_subject/admin/glucose_fbg_admin.py +18 -11
  363. meta_subject/admin/health_economics/__init__.py +2 -0
  364. meta_subject/admin/health_economics/health_economics_simple_admin.py +1 -1
  365. meta_subject/admin/health_economics/health_economics_update_admin.py +1 -1
  366. meta_subject/admin/hepatitis_test_admin.py +1 -1
  367. meta_subject/admin/hiv_exit_review_admin.py +55 -0
  368. meta_subject/admin/list_filters.py +5 -5
  369. meta_subject/admin/mnsi_admin.py +7 -5
  370. meta_subject/admin/next_appointment_admin.py +19 -0
  371. meta_subject/admin/other_arv_regimens_admin.py +3 -3
  372. meta_subject/admin/patient_history_admin.py +4 -4
  373. meta_subject/admin/physical_exam_admin.py +1 -1
  374. meta_subject/admin/pregnancy_update_admin.py +1 -1
  375. meta_subject/admin/study_medication_admin.py +8 -15
  376. meta_subject/admin/subject_requisition_admin.py +2 -2
  377. meta_subject/admin/subject_visit_admin.py +1 -1
  378. meta_subject/admin/subject_visit_missed_admin.py +1 -1
  379. meta_subject/admin/urine_dipstick_test_admin.py +1 -1
  380. meta_subject/admin/urine_pregnancy_admin.py +1 -1
  381. meta_subject/baker_recipes.py +15 -15
  382. meta_subject/choices.py +4 -3
  383. meta_subject/form_validators/__init__.py +15 -0
  384. meta_subject/form_validators/delivery_form_validator.py +3 -3
  385. meta_subject/form_validators/dm_endpoint_form_validator.py +3 -1
  386. meta_subject/form_validators/dm_followup_form_validator.py +8 -7
  387. meta_subject/form_validators/egfr_drop_notification_form_validator.py +1 -1
  388. meta_subject/form_validators/followup_examination_form_validator.py +1 -1
  389. meta_subject/form_validators/glucose_fbg_form_validator.py +76 -0
  390. meta_subject/form_validators/glucose_form_validator.py +10 -67
  391. meta_subject/form_validators/hiv_exit_review_form_validator.py +18 -0
  392. meta_subject/form_validators/mixins.py +95 -0
  393. meta_subject/forms/__init__.py +44 -0
  394. meta_subject/forms/blood_results/__init__.py +9 -0
  395. meta_subject/forms/blood_results/blood_results_hba1c_form.py +1 -1
  396. meta_subject/forms/blood_results/blood_results_rft_form.py +60 -4
  397. meta_subject/forms/delivery_form.py +2 -0
  398. meta_subject/forms/diabetes/__init__.py +2 -0
  399. meta_subject/forms/diabetes/dm_followup_form.py +2 -2
  400. meta_subject/forms/followup_vitals_form.py +27 -1
  401. meta_subject/forms/glucose_fbg_form.py +1 -46
  402. meta_subject/forms/health_economics/__init__.py +2 -0
  403. meta_subject/forms/hepatitis_test_form.py +1 -1
  404. meta_subject/forms/hiv_exit_review_form.py +13 -0
  405. meta_subject/forms/mixins.py +1 -1
  406. meta_subject/forms/next_appointment_form.py +36 -0
  407. meta_subject/forms/other_arv_regimens_form.py +1 -1
  408. meta_subject/forms/patient_history_form.py +1 -1
  409. meta_subject/forms/physical_exam_form.py +1 -1
  410. meta_subject/forms/pregnancy_update_form.py +1 -1
  411. meta_subject/forms/slider_widget.py +1 -1
  412. meta_subject/forms/study_medication_form.py +18 -12
  413. meta_subject/forms/subject_requisition_form.py +1 -1
  414. meta_subject/forms/subject_visit_missed_form.py +1 -1
  415. meta_subject/forms/urine_dipstick_test_form.py +1 -1
  416. meta_subject/forms/urine_pregnancy_form.py +1 -1
  417. meta_subject/management/commands/create_missing_refills.py +3 -3
  418. meta_subject/management/commands/create_missing_rx.py +2 -2
  419. meta_subject/management/commands/missed.py +20 -23
  420. meta_subject/metadata_rules/__init__.py +2 -0
  421. meta_subject/metadata_rules/metadata_rules.py +14 -0
  422. meta_subject/metadata_rules/predicates.py +44 -25
  423. meta_subject/migrations/0001_initial.py +61 -61
  424. meta_subject/migrations/0002_auto_20191021_0353.py +5 -5
  425. meta_subject/migrations/0012_auto_20200118_2334.py +5 -5
  426. meta_subject/migrations/0014_auto_20200120_1622.py +5 -5
  427. meta_subject/migrations/0018_coronakap_historicalcoronakap.py +5 -5
  428. meta_subject/migrations/0033_auto_20200516_2356.py +5 -5
  429. meta_subject/migrations/0038_auto_20200520_0020.py +5 -5
  430. meta_subject/migrations/0040_auto_20200527_2155.py +1 -1
  431. meta_subject/migrations/0045_auto_20200530_1801.py +1 -1
  432. meta_subject/migrations/0051_auto_20200617_2117.py +5 -5
  433. meta_subject/migrations/0063_auto_20210715_0337.py +5 -5
  434. meta_subject/migrations/0066_auto_20210721_0335.py +9 -9
  435. meta_subject/migrations/0067_auto_20210726_0340.py +5 -5
  436. meta_subject/migrations/0068_auto_20210728_1809.py +5 -5
  437. meta_subject/migrations/0072_auto_20210805_1545.py +7 -7
  438. meta_subject/migrations/0073_auto_20210809_0055.py +5 -5
  439. meta_subject/migrations/0077_auto_20210809_2323.py +3 -3
  440. meta_subject/migrations/0082_auto_20210823_1612.py +3 -3
  441. meta_subject/migrations/0083_auto_20210823_1620.py +3 -3
  442. meta_subject/migrations/0088_auto_20210924_0027.py +5 -5
  443. meta_subject/migrations/0090_auto_20210924_0424.py +5 -5
  444. meta_subject/migrations/0093_auto_20211117_0352.py +5 -5
  445. meta_subject/migrations/0095_auto_20220128_1719.py +5 -5
  446. meta_subject/migrations/0098_auto_20220309_2106.py +5 -5
  447. meta_subject/migrations/0101_auto_20220316_2147.py +13 -13
  448. meta_subject/migrations/0107_auto_20220415_0043.py +1 -1
  449. meta_subject/migrations/0115_historicalegfrnotification_egfrnotification.py +5 -13
  450. meta_subject/migrations/0128_auto_20220720_0055.py +1 -1
  451. meta_subject/migrations/0131_auto_20220722_0411.py +1 -1
  452. meta_subject/migrations/0135_auto_20220722_2212.py +2 -1
  453. meta_subject/migrations/0164_dmreferralfollowup_historicaldmreferralfollowup.py +5 -5
  454. meta_subject/migrations/0172_remove_historicalbloodresultsglu_action_item_and_more.py +1 -2
  455. meta_subject/migrations/0177_alter_bloodresultslft_alp_value_and_more.py +1 -2
  456. meta_subject/migrations/0178_historicalhealtheconomicsupdate_and_more.py +5 -14
  457. meta_subject/migrations/0186_healtheconomicsupdate_singleton_field_and_more.py +1 -2
  458. meta_subject/migrations/0187_dmdiagnosis_historicaldmdiagnosis_dmdxresult_and_more.py +5 -14
  459. meta_subject/migrations/0188_historicaldmdxresult_dmdxresult.py +5 -14
  460. meta_subject/migrations/0199_auto_20240516_0247.py +1 -1
  461. meta_subject/migrations/0209_remove_historicaldmdxresult_dm_diagnosis_and_more.py +1 -2
  462. meta_subject/migrations/0212_auto_20240827_2222.py +1 -1
  463. meta_subject/migrations/0216_historicalnextappointment_nextappointment.py +553 -0
  464. meta_subject/migrations/0217_alter_historicalnextappointment_appt_datetime_and_more.py +42 -0
  465. meta_subject/migrations/0218_alter_historicalnextappointment_appt_date_and_more.py +53 -0
  466. meta_subject/migrations/0219_remove_historicalnextappointment_allow_create_interim_and_more.py +92 -0
  467. meta_subject/migrations/0220_historicalbloodresultsgludummy_bloodresultsgludummy.py +825 -0
  468. meta_subject/migrations/0221_auto_20250402_1913.py +42 -0
  469. meta_subject/migrations/0222_alter_historicalstudymedication_stock_codes_and_more.py +46 -0
  470. meta_subject/migrations/0223_bloodresultsfbc_errors_bloodresultsgludummy_errors_and_more.py +83 -0
  471. meta_subject/migrations/0224_bloodresultsfbc_abnormal_summary_and_more.py +153 -0
  472. meta_subject/migrations/0225_followupvitals_waist_circumference_and_more.py +46 -0
  473. meta_subject/migrations/0226_followupvitals_waist_circumference_comment_and_more.py +97 -0
  474. meta_subject/migrations/0227_alter_followupvitals_waist_circumference_comment_and_more.py +97 -0
  475. meta_subject/migrations/0228_bloodresultshba1c_hba1c_datetime_and_more.py +2518 -0
  476. meta_subject/migrations/0229_alter_glucosefbg_consent_model_and_more.py +1918 -0
  477. meta_subject/migrations/0230_alter_historicaldelivery_action_identifier_and_more.py +1733 -0
  478. meta_subject/migrations/0231_alter_historicalmedicationadherence_consent_model_and_more.py +2054 -0
  479. meta_subject/migrations/0232_alter_patienthistory_concomitant_conditions_and_more.py +1170 -0
  480. meta_subject/migrations/0233_historicalspfq_spfq.py +1066 -0
  481. meta_subject/migrations/0234_remove_spfq_site_remove_spfq_subject_visit_and_more.py +27 -0
  482. meta_subject/migrations/0235_glucosefbg_endpoint_today_and_more.py +606 -0
  483. meta_subject/migrations/0236_alter_historicalhivexitreview_other_current_arv_regimen_and_more.py +58 -0
  484. meta_subject/migrations/0237_historicalhivexitreview_singleton_field_and_more.py +68 -0
  485. meta_subject/migrations/0238_historicalhivexitreview_available_and_more.py +88 -0
  486. meta_subject/model_mixins/__init__.py +10 -0
  487. meta_subject/model_mixins/arv_history_model_mixin.py +3 -44
  488. meta_subject/model_mixins/arv_review_model_mixin.py +53 -0
  489. meta_subject/model_mixins/search_slug_model_mixin.py +1 -2
  490. meta_subject/model_mixins/vitals_fields_model_mixin.py +33 -0
  491. meta_subject/models/__init__.py +52 -0
  492. meta_subject/models/birth_outcomes.py +3 -3
  493. meta_subject/models/blood_results/__init__.py +11 -0
  494. meta_subject/models/blood_results/blood_results_glu.py +29 -0
  495. meta_subject/models/blood_results/blood_results_hba1c.py +0 -1
  496. meta_subject/models/blood_results/blood_results_ins.py +0 -1
  497. meta_subject/models/blood_results/blood_results_lft.py +0 -1
  498. meta_subject/models/delivery.py +4 -6
  499. meta_subject/models/diabetes/__init__.py +2 -0
  500. meta_subject/models/diabetes/dm_endpoint.py +5 -5
  501. meta_subject/models/diabetes/dm_followup.py +7 -8
  502. meta_subject/models/diet_and_lifestyle.py +2 -2
  503. meta_subject/models/followup_examination.py +12 -14
  504. meta_subject/models/glucose.py +5 -5
  505. meta_subject/models/glucose_fbg.py +17 -4
  506. meta_subject/models/health_economics/__init__.py +2 -0
  507. meta_subject/models/health_economics/health_economics.py +8 -8
  508. meta_subject/models/health_economics/health_economics_simple.py +2 -2
  509. meta_subject/models/health_economics/health_economics_update.py +3 -2
  510. meta_subject/models/hepatitis_test.py +2 -2
  511. meta_subject/models/hiv_exit_review.py +44 -0
  512. meta_subject/models/next_appointment.py +15 -0
  513. meta_subject/models/other_arv_regimens_detail.py +1 -1
  514. meta_subject/models/patient_history.py +6 -7
  515. meta_subject/models/physical_exam.py +2 -2
  516. meta_subject/models/pregnancy_update.py +1 -1
  517. meta_subject/models/signals.py +15 -13
  518. meta_subject/models/subject_visit.py +2 -2
  519. meta_subject/models/todo.txt +1 -1
  520. meta_subject/models/urine_dipstick_test.py +2 -2
  521. meta_subject/models/urine_pregnancy.py +1 -1
  522. meta_subject/static/meta_subject/slider.css +1 -1
  523. meta_subject/templates/meta_subject/endpoint_review_instructions.html +1 -1
  524. meta_subject/templates/meta_subject/widgets/slider.html +0 -1
  525. meta_visit_schedule/visit_schedules/__init__.py +2 -0
  526. meta_visit_schedule/visit_schedules/phase_three/__init__.py +2 -0
  527. meta_visit_schedule/visit_schedules/phase_three/crfs.py +34 -1
  528. meta_visit_schedule/visit_schedules/phase_three/schedule.py +4 -4
  529. meta_visit_schedule/visit_schedules/phase_three/schedule_dm_referral.py +1 -2
  530. meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py +2 -3
  531. meta_ae/tests/holidays.csv +0 -15
  532. meta_ae/tests/tests/test_actions.py +0 -127
  533. meta_ae/tests/urls.py +0 -10
  534. meta_analytics/dataframes/enrolled/__init__.py +0 -1
  535. meta_analytics/dataframes/enrolled/get_glucose_df.py +0 -122
  536. meta_analytics/tests/__init__.py +0 -0
  537. meta_analytics/tests/test_endpoints_by_date.py +0 -94
  538. meta_consent/tests/__init__.py +0 -0
  539. meta_consent/tests/holidays.csv +0 -15
  540. meta_consent/tests/tests/__init__.py +0 -0
  541. meta_consent/tests/tests/test_form_validators.py +0 -110
  542. meta_consent/tests/tests/test_subject_consent.py +0 -10
  543. meta_consent/tests/urls.py +0 -17
  544. meta_dashboard/templates/meta_dashboard/bootstrap3/subject/dashboard.html +0 -11
  545. meta_dashboard/tests/__init__.py +0 -0
  546. meta_dashboard/tests/admin.py +0 -22
  547. meta_dashboard/tests/holidays.csv +0 -15
  548. meta_dashboard/tests/tests/__init__.py +0 -0
  549. meta_dashboard/tests/urls.py +0 -55
  550. meta_edc/tests/__init__.py +0 -0
  551. meta_edc/tests/tests/__init__.py +0 -0
  552. meta_edc/tests/tests/test_endpoints.py +0 -554
  553. meta_edc-0.3.39.dist-info/AUTHORS +0 -0
  554. meta_edc-0.3.39.dist-info/METADATA +0 -766
  555. meta_edc-0.3.39.dist-info/WHEEL +0 -5
  556. meta_edc-0.3.39.dist-info/top_level.txt +0 -20
  557. meta_labs/tests/__init__.py +0 -0
  558. meta_labs/tests/test_labs.py +0 -27
  559. meta_labs/tests/test_reportables.py +0 -16
  560. meta_labs/tests/urls.py +0 -4
  561. meta_lists/tests/__init__.py +0 -0
  562. meta_lists/tests/test_lists.py +0 -8
  563. meta_pharmacy/admin/actions.py +0 -38
  564. meta_prn/tests/__init__.py +0 -0
  565. meta_prn/tests/tests/__init__.py +0 -0
  566. meta_prn/tests/tests/test_actions.py +0 -97
  567. meta_prn/tests/tests/test_dm_referral.py +0 -206
  568. meta_prn/tests/tests/test_manager_order.py +0 -14
  569. meta_prn/tests/tests/test_pregnancy_notification.py +0 -93
  570. meta_prn/tests/urls.py +0 -10
  571. meta_rando/tests/__init__.py +0 -0
  572. meta_rando/tests/tests/__init__.py +0 -0
  573. meta_rando/tests/tests/test_randomizers.py +0 -57
  574. meta_reports/tests/__init__.py +0 -0
  575. meta_reports/tests/test_reports.py +0 -35
  576. meta_reports/tests/test_sql_gen.py +0 -5
  577. meta_reports/tests/urls.py +0 -4
  578. meta_screening/offline_models.py +0 -3
  579. meta_screening/tests/__init__.py +0 -0
  580. meta_screening/tests/holidays.csv +0 -15
  581. meta_screening/tests/meta_test_case_mixin.py +0 -216
  582. meta_screening/tests/options.py +0 -127
  583. meta_screening/tests/tests/__init__.py +0 -0
  584. meta_screening/tests/tests/test_forms.py +0 -397
  585. meta_screening/tests/tests/test_screening_part_one.py +0 -108
  586. meta_screening/tests/tests/test_screening_part_three.py +0 -436
  587. meta_screening/tests/tests/test_screening_part_two.py +0 -84
  588. meta_sites/tests/__init__.py +0 -0
  589. meta_sites/tests/test_sites.py +0 -12
  590. meta_sites/tests/urls.py +0 -4
  591. meta_stats/__init__.py +0 -0
  592. meta_stats/incidence.py +0 -16
  593. meta_stats/models.py +0 -0
  594. meta_stats/tests/__init__.py +0 -0
  595. meta_stats/tests/tests/__init__.py +0 -0
  596. meta_stats/tests/tests/test_incidence.py +0 -10
  597. meta_subject/tests/__init__.py +0 -0
  598. meta_subject/tests/holidays.csv +0 -15
  599. meta_subject/tests/tests/__init__.py +0 -0
  600. meta_subject/tests/tests/test_egfr.py +0 -234
  601. meta_subject/tests/tests/test_fixes.py +0 -64
  602. meta_subject/tests/tests/test_followup.py +0 -52
  603. meta_subject/tests/tests/test_manager_order.py +0 -11
  604. meta_subject/tests/tests/test_medication_adherence.py +0 -75
  605. meta_subject/tests/tests/test_metadata_rules.py +0 -135
  606. meta_subject/tests/tests/test_mnsi.py +0 -317
  607. meta_subject/tests/tests/test_patient_history_form.py +0 -74
  608. meta_subject/tests/tests/test_physical_exam.py +0 -84
  609. meta_subject/tests/tests/test_sf12.py +0 -173
  610. meta_subject/tests/tests/test_study_medication.py +0 -230
  611. meta_subject/tests/urls.py +0 -24
  612. meta_visit_schedule/tests/__init__.py +0 -0
  613. meta_visit_schedule/tests/tests/__init__.py +0 -0
  614. meta_visit_schedule/tests/tests/test_schedule.py +0 -181
  615. meta_visit_schedule/tests/urls.py +0 -4
  616. tests/__init__.py +0 -0
  617. tests/etc/randomization_list.csv +0 -241
  618. tests/etc/randomization_list_phase_three.csv +0 -241
  619. tests/etc/user-aes-local.key +0 -0
  620. tests/etc/user-aes-restricted.key +0 -1
  621. tests/etc/user-rsa-local-private.pem +0 -27
  622. tests/etc/user-rsa-local-public.pem +0 -9
  623. tests/etc/user-rsa-restricted-private.pem +0 -27
  624. tests/etc/user-rsa-restricted-public.pem +0 -9
  625. tests/etc/user-salt-local.key +0 -0
  626. tests/etc/user-salt-restricted.key +0 -0
  627. tests/holidays.csv +0 -15
  628. tests/test_settings.py +0 -186
  629. /meta_ae/templates/meta_ae/{bootstrap3/ae_initial_description.html → aeinitial_description.html} +0 -0
  630. /meta_dashboard/templates/meta_dashboard/{bootstrap3/buttons → buttons}/add_consent_button.html +0 -0
  631. /meta_dashboard/templates/meta_dashboard/{bootstrap3/buttons → buttons}/dashboard_button.html +0 -0
  632. /meta_dashboard/templates/meta_dashboard/{bootstrap3/buttons → buttons}/refusal_button.html +0 -0
  633. /meta_dashboard/templates/meta_dashboard/{bootstrap3/screening → screening}/listboard.html +0 -0
  634. /meta_dashboard/templates/meta_dashboard/{bootstrap3/subject → subject}/listboard.html +0 -0
  635. {meta_edc-0.3.39.dist-info → meta_edc-1.4.0.dist-info/licenses}/LICENSE +0 -0
  636. /meta_ae/tests/__init__.py → /meta_subject/management/__init__py.py +0 -0
  637. /meta_ae/tests/tests/__init__.py → /meta_subject/management/commands/__init__py.py +0 -0
@@ -1,2 +1,7 @@
1
1
  from .note_model_admin import MissingOgttNoteModelAdmin
2
2
  from .unmanaged_model_admin import MissingScreeningOgttAdmin
3
+
4
+ __all__ = [
5
+ "MissingOgttNoteModelAdmin",
6
+ "MissingScreeningOgttAdmin",
7
+ ]
@@ -1,6 +1,7 @@
1
1
  from django.contrib import admin
2
2
  from django_audit_fields import audit_fieldset_tuple
3
- from edc_qareports.modeladmin_mixins import NoteModelAdminMixin
3
+ from edc_model_admin.mixins import TemplatesModelAdminMixin
4
+ from edc_sites.admin import SiteModelAdminMixin
4
5
 
5
6
  from ....admin_site import meta_reports_admin
6
7
  from ....forms import MissingOgttNoteForm
@@ -9,7 +10,8 @@ from ....models import MissingOgttNote
9
10
 
10
11
  @admin.register(MissingOgttNote, site=meta_reports_admin)
11
12
  class MissingOgttNoteModelAdmin(
12
- NoteModelAdminMixin,
13
+ SiteModelAdminMixin,
14
+ TemplatesModelAdminMixin,
13
15
  admin.ModelAdmin,
14
16
  ):
15
17
  """A modeladmin class for the Note model."""
@@ -46,8 +48,30 @@ class MissingOgttNoteModelAdmin(
46
48
  audit_fieldset_tuple,
47
49
  )
48
50
 
49
- radio_fields = {
51
+ radio_fields = { # noqa: RUF012
50
52
  "ogtt_units": admin.VERTICAL,
51
53
  "result_status": admin.VERTICAL,
52
54
  "fasting": admin.VERTICAL,
53
55
  }
56
+
57
+ list_display = (
58
+ "subject_identifier",
59
+ "note",
60
+ "status",
61
+ "report_datetime",
62
+ )
63
+
64
+ # radio_fields = {"status": admin.VERTICAL}
65
+
66
+ list_filter = (
67
+ "report_datetime",
68
+ "status",
69
+ "report_model",
70
+ "user_created",
71
+ "user_modified",
72
+ )
73
+
74
+ search_fields = ("subject_identifier", "name")
75
+
76
+ def get_view_only_site_ids_for_user(self, request) -> list[int]:
77
+ return [s.id for s in request.user.userprofile.sites.all() if s.id != request.site.id]
@@ -32,9 +32,9 @@ class MissingScreeningOgttAdmin(
32
32
  note_template = "edc_qareports/columns/notes_column.html"
33
33
  include_note_column = True
34
34
 
35
- ordering = ["site", "subject_identifier"]
35
+ ordering = ("site", "subject_identifier")
36
36
 
37
- list_display = [
37
+ list_display = (
38
38
  "dashboard",
39
39
  "subject_identifier",
40
40
  "site",
@@ -49,17 +49,17 @@ class MissingScreeningOgttAdmin(
49
49
  "fbg2_datetime",
50
50
  "ogtt2_datetime",
51
51
  "consented",
52
- ]
52
+ )
53
53
 
54
- list_filter = [
54
+ list_filter = (
55
55
  ScheduleStatusListFilter,
56
56
  "screening_datetime",
57
57
  "fbg_datetime",
58
58
  "repeated",
59
59
  "p3_ltfu",
60
- ]
60
+ )
61
61
 
62
- search_fields = ["subject_identifier"]
62
+ search_fields = ("subject_identifier",)
63
63
 
64
64
  def dashboard(self, obj=None, label=None) -> str:
65
65
  url = self.get_subject_dashboard_url(obj=obj)
@@ -69,7 +69,7 @@ class MissingScreeningOgttAdmin(
69
69
  args=(obj.original_id,),
70
70
  )
71
71
  context = dict(title=_("Go to subject screening"), url=url, label=label)
72
- return render_to_string("dashboard_button.html", context=context)
72
+ return render_to_string("edc_subject_dashboard/dashboard_button.html", context=context)
73
73
 
74
74
  @admin.display(description="Screen date", ordering="screening_datetime")
75
75
  def screening_date(self, obj):
@@ -1 +1,3 @@
1
1
  from .unmanaged_model_admin import OnStudyMissingLabValuesAdmin
2
+
3
+ __all__ = ["OnStudyMissingLabValuesAdmin"]
@@ -7,7 +7,4 @@ from ....models import OnStudyMissingLabValues
7
7
 
8
8
  @admin.register(OnStudyMissingLabValues, site=meta_reports_admin)
9
9
  class OnStudyMissingLabValuesAdmin(OnStudyMissingValuesModelAdminMixin, admin.ModelAdmin):
10
-
11
10
  include_note_column: bool = True
12
-
13
- instructions = ["ello"]
@@ -1 +1,3 @@
1
1
  from .unmanaged_model_admin import OnStudyMissingValuesAdmin
2
+
3
+ __all__ = ["OnStudyMissingValuesAdmin"]
@@ -7,7 +7,6 @@ from ....models import OnStudyMissingValues
7
7
 
8
8
  @admin.register(OnStudyMissingValues, site=meta_reports_admin)
9
9
  class OnStudyMissingValuesAdmin(OnStudyMissingValuesModelAdminMixin, admin.ModelAdmin):
10
-
11
10
  include_note_column: bool = True
12
11
  project_reports_admin: str = "meta_reports_admin"
13
12
  project_subject_admin: str = "meta_subject_admin"
@@ -1,3 +1,5 @@
1
+ import contextlib
2
+
1
3
  from django.contrib import admin
2
4
  from django.core.exceptions import ObjectDoesNotExist
3
5
  from django.template.loader import render_to_string
@@ -23,8 +25,8 @@ class PatientHistoryMissingBaselineCd4Admin(
23
25
  TemplatesModelAdminMixin,
24
26
  admin.ModelAdmin,
25
27
  ):
26
- ordering = ["site", "subject_identifier"]
27
- list_display = [
28
+ ordering = ("site", "subject_identifier")
29
+ list_display = (
28
30
  "dashboard",
29
31
  "subject_identifier",
30
32
  "cd4",
@@ -33,15 +35,15 @@ class PatientHistoryMissingBaselineCd4Admin(
33
35
  "user_created",
34
36
  "user_modified",
35
37
  "modified",
36
- ]
38
+ )
37
39
 
38
- list_filter = [ScheduleStatusListFilter]
40
+ list_filter = (ScheduleStatusListFilter,)
39
41
 
40
- search_fields = ["subject_identifier"]
42
+ search_fields = ("subject_identifier",)
41
43
 
42
44
  def dashboard(self, obj=None, label=None) -> str:
43
45
  kwargs = self.get_subject_dashboard_url_kwargs(obj)
44
- try:
46
+ with contextlib.suppress(ObjectDoesNotExist):
45
47
  kwargs.update(
46
48
  appointment=str(
47
49
  Appointment.objects.get(
@@ -51,8 +53,6 @@ class PatientHistoryMissingBaselineCd4Admin(
51
53
  ).id
52
54
  )
53
55
  )
54
- except ObjectDoesNotExist:
55
- pass
56
56
  url = reverse(self.get_subject_dashboard_url_name(obj=obj), kwargs=kwargs)
57
57
  context = dict(title=_("Go to subject's dashboard@1000"), url=url, label=label)
58
- return render_to_string("dashboard_button.html", context=context)
58
+ return render_to_string("edc_subject_dashboard/dashboard_button.html", context=context)
@@ -17,9 +17,9 @@ class UnattendedThreeInRow2Admin(
17
17
  TemplatesModelAdminMixin,
18
18
  admin.ModelAdmin,
19
19
  ):
20
- ordering = ["site", "subject_identifier"]
20
+ ordering = ("site", "subject_identifier")
21
21
 
22
- list_display = [
22
+ list_display = (
23
23
  "dashboard",
24
24
  "subject",
25
25
  "first_value",
@@ -30,17 +30,17 @@ class UnattendedThreeInRow2Admin(
30
30
  "site",
31
31
  "missed_count",
32
32
  "created",
33
- ]
33
+ )
34
34
 
35
- list_filter = [
35
+ list_filter = (
36
36
  "missed_count",
37
37
  ScheduleStatusListFilter,
38
38
  "first_value",
39
39
  "second_value",
40
40
  "third_value",
41
- ]
41
+ )
42
42
 
43
- search_fields = ["id", "subject_identifier", "first_value", "second_value", "third_value"]
43
+ search_fields = ("id", "subject_identifier", "first_value", "second_value", "third_value")
44
44
 
45
45
  @admin.display(description="Subject", ordering="subject_identifier")
46
46
  def subject(self, obj):
@@ -17,8 +17,8 @@ class UnattendedThreeInRowAdmin(
17
17
  TemplatesModelAdminMixin,
18
18
  admin.ModelAdmin,
19
19
  ):
20
- ordering = ["site", "subject_identifier"]
21
- list_display = [
20
+ ordering = ("site", "subject_identifier")
21
+ list_display = (
22
22
  "dashboard",
23
23
  "subject_identifier",
24
24
  "first_value",
@@ -28,8 +28,8 @@ class UnattendedThreeInRowAdmin(
28
28
  "from_now_days",
29
29
  "site",
30
30
  "created",
31
- ]
31
+ )
32
32
 
33
- list_filter = [ScheduleStatusListFilter, "first_value", "second_value", "third_value"]
33
+ list_filter = (ScheduleStatusListFilter, "first_value", "second_value", "third_value")
34
34
 
35
- search_fields = ["subject_identifier", "first_value", "second_value", "third_value"]
35
+ search_fields = ("subject_identifier", "first_value", "second_value", "third_value")
@@ -17,8 +17,8 @@ class UnattendedTwoInRowAdmin(
17
17
  TemplatesModelAdminMixin,
18
18
  admin.ModelAdmin,
19
19
  ):
20
- ordering = ["site", "subject_identifier"]
21
- list_display = [
20
+ ordering = ("site", "subject_identifier")
21
+ list_display = (
22
22
  "dashboard",
23
23
  "subject_identifier",
24
24
  "first_value",
@@ -27,8 +27,8 @@ class UnattendedTwoInRowAdmin(
27
27
  "from_now_days",
28
28
  "site",
29
29
  "created",
30
- ]
30
+ )
31
31
 
32
- list_filter = [ScheduleStatusListFilter, "first_value", "second_value"]
32
+ list_filter = (ScheduleStatusListFilter, "first_value", "second_value")
33
33
 
34
- search_fields = ["subject_identifier", "first_value", "second_value"]
34
+ search_fields = ("subject_identifier", "first_value", "second_value")
@@ -8,7 +8,7 @@ from .modeladmin_mixins import EndpointsModelAdminMixin
8
8
 
9
9
  @admin.register(Endpoints, site=meta_reports_admin)
10
10
  class EndpointsAdmin(EndpointsModelAdminMixin, admin.ModelAdmin):
11
- queryset_filter = dict(offstudy_date__isnull=True)
11
+ queryset_filter = dict(offstudy_date__isnull=True) # noqa: RUF012
12
12
 
13
13
  def rendered_change_list_note(self):
14
14
  return render_to_string("meta_reports/endpoints_change_list_note.html")
@@ -8,6 +8,5 @@ from .modeladmin_mixins import EndpointsModelAdminMixin
8
8
 
9
9
  @admin.register(EndpointsProxy, site=meta_reports_admin)
10
10
  class EndpointsAllAdmin(EndpointsModelAdminMixin, admin.ModelAdmin):
11
-
12
11
  def rendered_change_list_note(self):
13
12
  return render_to_string("meta_reports/endpoints_all_change_list_note.html")
@@ -1,16 +1,18 @@
1
+ import pandas as pd
1
2
  from django.contrib import admin, messages
2
3
  from django.core.exceptions import FieldDoesNotExist
3
4
  from django.db import models
4
5
  from django.db.models import QuerySet
5
- from django.utils.html import format_html
6
+ from django.template.loader import render_to_string
7
+ from django.utils.safestring import mark_safe
6
8
  from edc_model_admin.dashboard import ModelAdminDashboardMixin
7
9
  from edc_model_admin.list_filters import PastDateListFilter
8
10
  from edc_model_admin.mixins import TemplatesModelAdminMixin
9
- from edc_pdutils.actions import export_to_csv
10
11
  from edc_qareports.modeladmin_mixins import QaReportModelAdminMixin
11
12
  from edc_sites.admin import SiteModelAdminMixin
12
13
  from edc_sites.admin.list_filters import SiteListFilter
13
14
  from edc_utils import get_utcnow
15
+ from rangefilter.filters import DateRangeFilterBuilder
14
16
 
15
17
  from meta_analytics.dataframes import get_last_imp_visits_df
16
18
 
@@ -32,7 +34,7 @@ class NextApptDateListFilter(PastDateListFilter):
32
34
  field_name = "next_appt_date"
33
35
 
34
36
 
35
- def update_report(modeladmin, request, queryset):
37
+ def update_report(modeladmin, request, queryset): # noqa: ARG001
36
38
  now = get_utcnow()
37
39
  modeladmin.model.objects.all().delete()
38
40
  df = get_last_imp_visits_df()
@@ -41,21 +43,31 @@ def update_report(modeladmin, request, queryset):
41
43
  modeladmin.model(
42
44
  subject_identifier=row["subject_identifier"],
43
45
  site_id=row["site_id"],
44
- imp_visit_date=row["imp_visit_date"],
46
+ imp_visit_date=(
47
+ None if pd.isna(row["imp_visit_date"]) else row["imp_visit_date"]
48
+ ),
45
49
  imp_visit_code=row["imp_visit_code"],
46
- next_appt_date=row["next_appt_datetime"],
47
- next_visit_code=row["next_visit_code"],
50
+ next_appt_date=(
51
+ None if pd.isna(row["next_appt_datetime"]) else row["next_appt_datetime"]
52
+ ),
53
+ next_visit_code=(
54
+ None if pd.isna(row["next_visit_code"]) else row["next_visit_code"]
55
+ ),
48
56
  days_since=row["days_since"].days,
49
- days_until=row["days_until"].days,
50
- visit_code=str(int(row["imp_visit_code"])),
51
- visit_code_sequence=row["imp_visit_code"] % 1,
57
+ days_until=None if pd.isna(row["days_until"]) else row["days_until"].days,
58
+ visit_code=(
59
+ None if pd.isna(row["imp_visit_code"]) else str(int(row["imp_visit_code"]))
60
+ ),
61
+ visit_code_sequence=(
62
+ None if pd.isna(row["imp_visit_code"]) else row["imp_visit_code"] % 1
63
+ ),
52
64
  report_model=modeladmin.model._meta.label_lower,
53
65
  created=now,
54
66
  )
55
67
  for _, row in df.iterrows()
56
68
  ]
57
69
  created = len(modeladmin.model.objects.bulk_create(data))
58
- messages.success(request, "{} records were successfully created.".format(created))
70
+ messages.success(request, f"{created} records were successfully created.")
59
71
 
60
72
 
61
73
  @admin.register(LastImpRefill, site=meta_reports_admin)
@@ -70,28 +82,13 @@ class LastImpRefillAdmin(
70
82
 
71
83
  change_list_title = "List of most recent IMP refills per subject"
72
84
 
73
- change_list_note = format_html(
74
- """
75
- This report fetches the most recent Study Medication report where IMP was
76
- refilled and adds the subject's next visit. Subjects taken "Off Schedule"
77
- are not included in this report. To update ALL rows in this report, tick
78
- at least one row and select 'Update report' action below.
79
- <BR><BR>
80
- This report has additional search features for numeric columns:
81
- <code>days_since</code>, <code>days_until</code>, <code>imp_visit_code</code>
82
- and <code>next_visit_code</code>.
83
- <BR><BR>For example, type <code>days_until>=25</code> in the search below
84
- to show rows for subjects who have an appointment 25 or more days from the
85
- date this report was created. You might also try typing
86
- <code>days_since>365</code> or <code>days_until<0</code>.
87
- <BR><BR>
88
- This also works: <code>next_visit_code>=1060</code>.
89
- """
90
- )
85
+ change_list_note = mark_safe( # noqa: S308
86
+ render_to_string("meta_reports/last_imp_refill/changelist_note.html")
87
+ ) # nosec B308, B703
91
88
 
92
- actions = [update_report, export_to_csv]
89
+ actions = (update_report,)
93
90
 
94
- list_display = [
91
+ list_display = (
95
92
  "dashboard",
96
93
  "subject_identifier",
97
94
  "imp_visit_code",
@@ -101,17 +98,17 @@ class LastImpRefillAdmin(
101
98
  "next_appt_date",
102
99
  "days_until",
103
100
  "created",
104
- ]
101
+ )
105
102
 
106
- list_filter = [
107
- ImpVisitDateListFilter,
108
- NextApptDateListFilter,
103
+ list_filter = (
104
+ ("imp_visit_date", DateRangeFilterBuilder()),
105
+ ("next_appt_date", DateRangeFilterBuilder()),
109
106
  "imp_visit_code",
110
107
  "next_visit_code",
111
108
  SiteListFilter,
112
- ]
109
+ )
113
110
 
114
- search_fields = ["subject_identifier"]
111
+ search_fields = ("subject_identifier",)
115
112
 
116
113
  def get_queryset(self, request) -> QuerySet:
117
114
  qs = super().get_queryset(request)
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import NO, YES
1
2
  from django.contrib.admin import SimpleListFilter
2
- from edc_constants.constants import NO, YES
3
3
 
4
4
  from meta_reports.models import Endpoints
5
5
 
@@ -8,13 +8,13 @@ class EndpointListFilter(SimpleListFilter):
8
8
  title = "Endpoint"
9
9
  parameter_name = "endpoint"
10
10
 
11
- def lookups(self, request, model_admin):
11
+ def lookups(self, request, model_admin): # noqa: ARG002
12
12
  return (
13
13
  (YES, YES),
14
14
  (NO, NO),
15
15
  )
16
16
 
17
- def queryset(self, request, queryset):
17
+ def queryset(self, request, queryset): # noqa: ARG002
18
18
  if self.value() == YES:
19
19
  return queryset.filter(
20
20
  subject_identifier__in=Endpoints.objects.values_list(
@@ -1,5 +1,3 @@
1
- from typing import Type
2
-
3
1
  from django.conf import settings
4
2
  from django.contrib import admin
5
3
  from django.contrib.admin import SimpleListFilter
@@ -16,7 +14,7 @@ from edc_visit_schedule.admin import ScheduleStatusListFilter
16
14
  from ..tasks import update_endpoints_table
17
15
 
18
16
 
19
- def update_endpoints_table_action(modeladmin, request, queryset):
17
+ def update_endpoints_table_action(modeladmin, request, queryset): # noqa: ARG001
20
18
  subject_identifiers = []
21
19
  if queryset.count() != modeladmin.model.objects.count():
22
20
  subject_identifiers = [o.subject_identifier for o in queryset]
@@ -35,10 +33,10 @@ class EndpointsModelAdminMixin(
35
33
  TemplatesModelAdminMixin,
36
34
  ):
37
35
  queryset_filter: dict | None = None
38
- actions = [update_endpoints_table_action]
36
+ actions = (update_endpoints_table_action,)
39
37
  qa_report_list_display_insert_pos = 3
40
- ordering = ["-fbg_date"]
41
- list_display = [
38
+ ordering = ("-fbg_date",)
39
+ list_display = (
42
40
  "dashboard",
43
41
  "subject",
44
42
  "visit",
@@ -50,15 +48,15 @@ class EndpointsModelAdminMixin(
50
48
  "last_updated",
51
49
  "offstudy_date",
52
50
  "offstudy_reason",
53
- ]
51
+ )
54
52
 
55
- list_filter = [
53
+ list_filter = (
56
54
  "endpoint_label",
57
55
  ScheduleStatusListFilter,
58
56
  SiteListFilter,
59
- ]
57
+ )
60
58
 
61
- search_fields = ["subject_identifier"]
59
+ search_fields = ("subject_identifier",)
62
60
 
63
61
  def get_queryset(self, request) -> QuerySet:
64
62
  qs = super().get_queryset(request)
@@ -66,10 +64,9 @@ class EndpointsModelAdminMixin(
66
64
  qs = qs.filter(**self.queryset_filter)
67
65
  return qs
68
66
 
69
- def get_list_filter(self, request) -> tuple[str | Type[SimpleListFilter], ...]:
67
+ def get_list_filter(self, request) -> tuple[str | type[SimpleListFilter], ...]:
70
68
  list_filter = super().get_list_filter(request)
71
- list_filter = list_filter + (SiteListFilter,)
72
- return list_filter
69
+ return *list_filter, SiteListFilter
73
70
 
74
71
  @admin.display(description="subject", ordering="subject_identifier")
75
72
  def subject(self, obj=None):
@@ -79,10 +76,6 @@ class EndpointsModelAdminMixin(
79
76
  def visit(self, obj=None):
80
77
  return obj.visit_code
81
78
 
82
- # @admin.display(description="FBG DATE", ordering="fbg_date")
83
- # def fbg_date(self, obj=None):
84
- # return obj.fbg_datetime.date() if obj.fbg_datetime else None
85
-
86
79
  @admin.display(description="FAST", ordering="fasting")
87
80
  def fast(self, obj=None):
88
81
  return obj.fasting
@@ -1,8 +1,8 @@
1
1
  from textwrap import fill
2
2
 
3
3
  import inflect
4
+ from clinicedc_constants import OTHER, TUBERCULOSIS
4
5
  from django.contrib.auth import get_user_model
5
- from edc_constants.constants import OTHER, TUBERCULOSIS
6
6
  from reportlab.lib import colors
7
7
  from reportlab.lib.units import cm
8
8
  from reportlab.platypus.flowables import Spacer
@@ -24,7 +24,7 @@ class DeathPdfReport(MetaCrfPdfReport):
24
24
  super().__init__(**kwargs)
25
25
  self.death_report = death_report
26
26
 
27
- def get_report_story(self, **kwargs):
27
+ def get_report_story(self, **kwargs): # noqa: ARG002
28
28
  story = []
29
29
 
30
30
  self.draw_demographics(story)
@@ -1 +1,3 @@
1
1
  from .missing_ogtt_note_form import MissingOgttNoteForm
2
+
3
+ __all__ = ["MissingOgttNoteForm"]
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import NO, YES
1
2
  from django import forms
2
- from edc_constants.constants import NO, YES
3
3
  from edc_form_validators import FormValidator, FormValidatorMixin
4
4
  from edc_glucose.form_validators import OgttFormValidatorMixin
5
5
  from edc_glucose.utils import validate_glucose_as_millimoles_per_liter
@@ -8,7 +8,6 @@ from ..models import MissingOgttNote
8
8
 
9
9
 
10
10
  class MissingOgttNoteFormValidator(OgttFormValidatorMixin, FormValidator):
11
-
12
11
  def clean(self):
13
12
  self.applicable_if(YES, field="result_status", field_applicable="fasting")
14
13
  self.required_if(YES, NO, field="fasting", field_required="ogtt_base_datetime")
@@ -26,8 +25,8 @@ class MissingOgttNoteForm(FormValidatorMixin, forms.ModelForm):
26
25
  class Meta:
27
26
  model = MissingOgttNote
28
27
  fields = "__all__"
29
- help_text = {"subject_identifier": "(read-only)", "name": "(read-only)"}
30
- widgets = {
28
+ help_text = {"subject_identifier": "(read-only)", "name": "(read-only)"} # noqa: RUF012
29
+ widgets = { # noqa: RUF012
31
30
  "report_model": forms.TextInput(attrs={"readonly": "readonly"}),
32
31
  "subject_identifier": forms.TextInput(attrs={"readonly": "readonly"}),
33
32
  }
@@ -1,13 +1,14 @@
1
+ import sys
2
+
1
3
  from django.core.management import BaseCommand
2
4
 
3
5
  from meta_analytics.dataframes import GlucoseEndpointsByDate
4
6
 
5
7
 
6
8
  class Command(BaseCommand):
7
-
8
- def handle(self, *args, **options):
9
- print("Generating endpoints...")
9
+ def handle(self, *args, **options): # noqa: ARG002
10
+ sys.stdout.write("Generating endpoints...\n")
10
11
  cls = GlucoseEndpointsByDate()
11
12
  cls.run()
12
13
  cls.to_model()
13
- print("Generating endpoints... done.")
14
+ sys.stdout.write("Generating endpoints... done.\n")
@@ -6,7 +6,7 @@ import django.db.models.manager
6
6
  import django_audit_fields.fields.hostname_modification_field
7
7
  import django_audit_fields.fields.userfield
8
8
  import django_audit_fields.fields.uuid_auto_field
9
- import django_audit_fields.models.audit_model_mixin
9
+ import django.utils.timezone
10
10
  import django_revision.revision_field
11
11
  import edc_model.validators.date
12
12
  import edc_sites.managers
@@ -18,7 +18,6 @@ from django.db import migrations, models
18
18
 
19
19
 
20
20
  class Migration(migrations.Migration):
21
-
22
21
  dependencies = [
23
22
  ("meta_reports", "0034_auto_20240823_1642"),
24
23
  ("sites", "0002_alter_domain_unique"),
@@ -42,15 +41,11 @@ class Migration(migrations.Migration):
42
41
  ),
43
42
  (
44
43
  "created",
45
- models.DateTimeField(
46
- blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
47
- ),
44
+ models.DateTimeField(blank=True, default=django.utils.timezone.now),
48
45
  ),
49
46
  (
50
47
  "modified",
51
- models.DateTimeField(
52
- blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
53
- ),
48
+ models.DateTimeField(blank=True, default=django.utils.timezone.now),
54
49
  ),
55
50
  (
56
51
  "user_created",
@@ -262,15 +257,11 @@ class Migration(migrations.Migration):
262
257
  ),
263
258
  (
264
259
  "created",
265
- models.DateTimeField(
266
- blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
267
- ),
260
+ models.DateTimeField(blank=True, default=django.utils.timezone.now),
268
261
  ),
269
262
  (
270
263
  "modified",
271
- models.DateTimeField(
272
- blank=True, default=django_audit_fields.models.audit_model_mixin.utcnow
273
- ),
264
+ models.DateTimeField(blank=True, default=django.utils.timezone.now),
274
265
  ),
275
266
  (
276
267
  "user_created",