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
@@ -0,0 +1,95 @@
1
+ from decimal import Decimal
2
+
3
+ from clinicedc_constants import NO, PENDING, YES
4
+ from edc_form_validators import INVALID_ERROR
5
+
6
+ from meta_reports.models import GlucoseSummary
7
+
8
+
9
+ class EndpointValidatorMixin:
10
+ def validate_endpoint_fields(self):
11
+ is_endpoint = self.is_endpoint()
12
+ if is_endpoint == YES and self.cleaned_data.get("endpoint_today") != YES:
13
+ self.raise_validation_error(
14
+ {
15
+ "endpoint_today": (
16
+ "Participant has reached a study endpoint today. Expected YES"
17
+ )
18
+ },
19
+ INVALID_ERROR,
20
+ )
21
+ elif is_endpoint == PENDING and self.cleaned_data.get("endpoint_today") != PENDING:
22
+ self.raise_validation_error(
23
+ {
24
+ "endpoint_today": (
25
+ "Participant has not reached a study endpoint today. "
26
+ "Expected to repeat FBG"
27
+ )
28
+ },
29
+ INVALID_ERROR,
30
+ )
31
+
32
+ elif is_endpoint == NO and self.cleaned_data.get("endpoint_today") != NO:
33
+ self.raise_validation_error(
34
+ {"endpoint_today": "Participant has not reached a study endpoint today"},
35
+ INVALID_ERROR,
36
+ )
37
+
38
+ def is_endpoint(self):
39
+ value = NO
40
+ if (
41
+ self.cleaned_data.get("fbg_value")
42
+ and self.cleaned_data.get("ogtt_value")
43
+ and self.cleaned_data.get("fbg_value") >= Decimal("7.0")
44
+ and self.cleaned_data.get("ogtt_value") >= Decimal("11.1")
45
+ ) or (
46
+ self.cleaned_data.get("fbg_value")
47
+ and self.cleaned_data.get("ogtt_value")
48
+ and self.cleaned_data.get("fbg_value") < Decimal("7.0")
49
+ and self.cleaned_data.get("ogtt_value") >= Decimal("11.1")
50
+ ):
51
+ value = YES
52
+ elif (
53
+ self.cleaned_data.get("fbg_value")
54
+ and self.cleaned_data.get("ogtt_value")
55
+ and self.cleaned_data.get("fbg_value") >= Decimal("7.0")
56
+ and self.cleaned_data.get("ogtt_value") < Decimal("11.1")
57
+ ):
58
+ # is there a previous FBG>=7.0 in sequence or do you need to repeat?
59
+ previous_obj = (
60
+ GlucoseSummary.objects.filter(
61
+ subject_identifier=self.subject_identifier,
62
+ fbg_datetime__lt=self.cleaned_data.get("fbg_datetime"),
63
+ )
64
+ .order_by("fbg_datetime")
65
+ .last()
66
+ )
67
+ if previous_obj and previous_obj.fbg_value >= Decimal("7.0"):
68
+ value = YES
69
+ else:
70
+ # you need to schedule a repeat
71
+ value = PENDING
72
+ return value
73
+
74
+
75
+ class RepeatFbgDateValidatorMixin:
76
+ def validate_repeat_fbg_date(self):
77
+ if self.cleaned_data.get("repeat_fbg_date"):
78
+ delta = (
79
+ self.cleaned_data.get("repeat_fbg_date")
80
+ - self.cleaned_data.get("fbg_datetime").date()
81
+ )
82
+ if delta.days < 7:
83
+ self.raise_validation_error(
84
+ {"repeat_fbg_date": "Must be at least 7 days from the FBG date above"},
85
+ INVALID_ERROR,
86
+ )
87
+ if delta.days > 10:
88
+ self.raise_validation_error(
89
+ {
90
+ "repeat_fbg_date": (
91
+ "Must be no more than 10 days from the FBG date above"
92
+ )
93
+ },
94
+ INVALID_ERROR,
95
+ )
@@ -19,9 +19,11 @@ from .glucose_fbg_form import GlucoseFbgForm
19
19
  from .glucose_form import GlucoseForm
20
20
  from .health_economics import HealthEconomicsSimpleForm, HealthEconomicsUpdateForm
21
21
  from .hepatitis_test_form import HepatitisTestForm
22
+ from .hiv_exit_review_form import HivExitReviewForm
22
23
  from .malaria_test_form import MalariaTestForm
23
24
  from .medication_adherence_form import MedicationAdherenceForm
24
25
  from .mnsi_form import MnsiForm
26
+ from .next_appointment_form import NextAppointmentForm
25
27
  from .other_arv_regimens_detail_form import OtherArvRegimensDetailForm
26
28
  from .other_arv_regimens_form import OtherArvRegimensForm
27
29
  from .patient_history_form import PatientHistoryForm
@@ -34,3 +36,45 @@ from .subject_visit_form import SubjectVisitForm
34
36
  from .subject_visit_missed_form import SubjectVisitMissedForm
35
37
  from .urine_dipstick_test_form import UrineDipstickTestForm
36
38
  from .urine_pregnancy_form import UrinePregnancyForm
39
+
40
+ __all__ = [
41
+ "BirthOutcomesForm",
42
+ "BloodResultsFbcForm",
43
+ "BloodResultsHba1cForm",
44
+ "BloodResultsInsForm",
45
+ "BloodResultsInsForm",
46
+ "BloodResultsLftForm",
47
+ "BloodResultsLipidsForm",
48
+ "BloodResultsRftForm",
49
+ "ComplicationsGlycemiaForm",
50
+ "ConcomitantMedicationForm",
51
+ "DeliveryForm",
52
+ "DmEndpointForm",
53
+ "DmFollowupForm",
54
+ "EgfrDropNotificationForm",
55
+ "Eq5d3lForm",
56
+ "FollowupExaminationForm",
57
+ "FollowupVitalsForm",
58
+ "GlucoseFbgForm",
59
+ "GlucoseForm",
60
+ "HealthEconomicsSimpleForm",
61
+ "HealthEconomicsUpdateForm",
62
+ "HepatitisTestForm",
63
+ "HivExitReviewForm",
64
+ "MalariaTestForm",
65
+ "MedicationAdherenceForm",
66
+ "MnsiForm",
67
+ "NextAppointmentForm",
68
+ "OtherArvRegimensDetailForm",
69
+ "OtherArvRegimensForm",
70
+ "PatientHistoryForm",
71
+ "PhysicalExamForm",
72
+ "PregnancyUpdateForm",
73
+ "Sf12Form",
74
+ "StudyMedicationForm",
75
+ "SubjectRequisitionForm",
76
+ "SubjectVisitForm",
77
+ "SubjectVisitMissedForm",
78
+ "UrineDipstickTestForm",
79
+ "UrinePregnancyForm",
80
+ ]
@@ -4,3 +4,12 @@ from .blood_results_ins_form import BloodResultsInsForm
4
4
  from .blood_results_lft_form import BloodResultsLftForm
5
5
  from .blood_results_lipids_form import BloodResultsLipidsForm
6
6
  from .blood_results_rft_form import BloodResultsRftForm
7
+
8
+ __all__ = [
9
+ "BloodResultsFbcForm",
10
+ "BloodResultsHba1cForm",
11
+ "BloodResultsInsForm",
12
+ "BloodResultsLftForm",
13
+ "BloodResultsLipidsForm",
14
+ "BloodResultsRftForm",
15
+ ]
@@ -9,7 +9,7 @@ from ...models import BloodResultsHba1c
9
9
 
10
10
 
11
11
  class BloodResultsHba1cFormValidator(BloodResultsFormValidatorMixin, CrfFormValidator):
12
- panels = [hba1c_poc_panel, hba1c_panel]
12
+ panels = (hba1c_poc_panel, hba1c_panel)
13
13
 
14
14
 
15
15
  class BloodResultsHba1cForm(ActionItemCrfFormMixin, CrfModelFormMixin, forms.ModelForm):
@@ -3,21 +3,77 @@ from django.utils.safestring import mark_safe
3
3
  from edc_action_item.forms import ActionItemCrfFormMixin
4
4
  from edc_crf.crf_form_validator import CrfFormValidator
5
5
  from edc_crf.modelform_mixins import CrfModelFormMixin
6
+ from edc_egfr.form_validator_mixins import EgfrCkdEpiFormValidatorMixin
6
7
  from edc_lab_panel.panels import rft_panel
7
8
  from edc_lab_results.form_validator_mixins import BloodResultsFormValidatorMixin
8
- from edc_reportable import BmiFormValidatorMixin
9
+ from edc_registration.models import RegisteredSubject
10
+ from edc_utils import age
11
+ from edc_visit_schedule.utils import is_baseline
12
+ from edc_vitals.form_validators import BmiFormValidatorMixin
9
13
 
10
- from ...models import BloodResultsRft
14
+ from meta_visit_schedule.constants import DAY1
15
+
16
+ from ...models import BloodResultsRft, FollowupVitals, PhysicalExam, SubjectVisit
11
17
 
12
18
 
13
19
  class BloodResultsRftFormValidator(
14
- BloodResultsFormValidatorMixin, BmiFormValidatorMixin, CrfFormValidator
20
+ BloodResultsFormValidatorMixin,
21
+ EgfrCkdEpiFormValidatorMixin,
22
+ BmiFormValidatorMixin,
23
+ CrfFormValidator,
15
24
  ):
16
25
  panel = rft_panel
17
26
 
18
27
  def clean(self):
19
28
  super().clean()
20
29
  self.validate_bmi()
30
+ if self.cleaned_data.get("creatinine_value") and self.cleaned_data.get(
31
+ "creatinine_units"
32
+ ):
33
+ if is_baseline(self.related_visit):
34
+ baseline_egfr_value = None
35
+ else:
36
+ baseline_visit = SubjectVisit.objects.get(
37
+ subject_identifier=self.related_visit.subject_identifier,
38
+ visit_code=DAY1,
39
+ visit_code_sequence=0,
40
+ )
41
+ baseline_egfr_value = BloodResultsRft.objects.get(
42
+ subject_visit=baseline_visit
43
+ ).egfr_value
44
+ rs = RegisteredSubject.objects.get(
45
+ subject_identifier=self.related_visit.subject_identifier
46
+ )
47
+ age_in_years = age(rs.dob, self.report_datetime).years
48
+
49
+ self.validate_egfr(
50
+ gender=rs.gender,
51
+ age_in_years=age_in_years,
52
+ ethnicity=rs.ethnicity,
53
+ weight_in_kgs=self.get_weight_in_kgs(),
54
+ baseline_egfr_value=baseline_egfr_value,
55
+ )
56
+
57
+ def get_weight_in_kgs(self) -> float | None:
58
+ if is_baseline(self.related_visit):
59
+ obj = (
60
+ PhysicalExam.objects.filter(
61
+ subject_visit=self.related_visit, weight__isnull=False
62
+ )
63
+ .order_by("report_datetime")
64
+ .last()
65
+ )
66
+ else:
67
+ obj = (
68
+ FollowupVitals.objects.filter(
69
+ subject_visit=self.related_visit, weight__isnull=False
70
+ )
71
+ .order_by("report_datetime")
72
+ .last()
73
+ )
74
+ if obj:
75
+ return obj.weight
76
+ return None
21
77
 
22
78
 
23
79
  class BloodResultsRftForm(ActionItemCrfFormMixin, CrfModelFormMixin, forms.ModelForm):
@@ -26,7 +82,7 @@ class BloodResultsRftForm(ActionItemCrfFormMixin, CrfModelFormMixin, forms.Model
26
82
  class Meta(ActionItemCrfFormMixin.Meta):
27
83
  model = BloodResultsRft
28
84
  fields = "__all__"
29
- help_texts = {
85
+ help_texts = { # noqa: RUF012
30
86
  "action_identifier": "(read-only)",
31
87
  "egfr_value": mark_safe( # nosec B308
32
88
  "Calculated using 2009 CKD-EPI Creatinine. "
@@ -7,6 +7,8 @@ from ..models import Delivery
7
7
 
8
8
 
9
9
  class DeliveryForm(CrfModelFormMixin, ActionItemCrfFormMixin, forms.ModelForm):
10
+ report_datetime_allowance = 364
11
+
10
12
  form_validator_cls = DeliveryFormValidator
11
13
 
12
14
  class Meta(ActionItemCrfFormMixin.Meta):
@@ -1,2 +1,4 @@
1
1
  from .dm_endpoint_form import DmEndpointForm
2
2
  from .dm_followup_form import DmFollowupForm
3
+
4
+ __all__ = ["DmEndpointForm", "DmFollowupForm"]
@@ -17,8 +17,8 @@ class DmFollowupForm(CrfModelFormMixin, ActionItemCrfFormMixin, forms.ModelForm)
17
17
  class Meta:
18
18
  model = DmFollowup
19
19
  fields = "__all__"
20
- help_text = {"action_identifier": "(read-only)"}
21
- widgets = {
20
+ help_text = {"action_identifier": "(read-only)"} # noqa: RUF012
21
+ widgets = { # noqa: RUF012
22
22
  "action_identifier": forms.TextInput(
23
23
  attrs={"required": False, "readonly": "readonly"}
24
24
  ),
@@ -1,12 +1,38 @@
1
+ from clinicedc_constants import NO, YES
1
2
  from django import forms
2
3
  from edc_crf.crf_form_validator import CrfFormValidator
3
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
+ from edc_visit_schedule.constants import MONTH36, MONTH48
4
6
 
5
7
  from ..models import FollowupVitals
6
8
 
7
9
 
10
+ class FollowupVitalsFormValidator(CrfFormValidator):
11
+ def clean(self):
12
+ self.required_if(
13
+ YES, field="waist_circumference_measured", field_required="waist_circumference"
14
+ )
15
+
16
+ visit_code = (
17
+ f"{self.related_visit.visit_code}.{self.related_visit.visit_code_sequence}"
18
+ )
19
+ require_waist_circumference_comment = bool(
20
+ visit_code in [f"{MONTH36}.0", f"{MONTH48}.0"]
21
+ or self.cleaned_data.get("waist_circumference_measured") == YES
22
+ )
23
+
24
+ if (
25
+ self.cleaned_data.get("waist_circumference_measured")
26
+ and self.cleaned_data.get("waist_circumference_measured") == NO
27
+ ):
28
+ self.required_if_true(
29
+ require_waist_circumference_comment,
30
+ field_required="waist_circumference_comment",
31
+ )
32
+
33
+
8
34
  class FollowupVitalsForm(CrfModelFormMixin, forms.ModelForm):
9
- form_validator_cls = CrfFormValidator
35
+ form_validator_cls = FollowupVitalsFormValidator
10
36
 
11
37
  class Meta:
12
38
  model = FollowupVitals
@@ -1,55 +1,10 @@
1
- from decimal import Decimal
2
-
3
1
  from django import forms
4
- from edc_constants.constants import NO, YES
5
- from edc_crf.crf_form_validator import CrfFormValidator
6
2
  from edc_crf.modelform_mixins import CrfModelFormMixin
7
- from edc_form_validators import INVALID_ERROR
8
- from edc_glucose.utils import validate_glucose_as_millimoles_per_liter
9
3
 
4
+ from ..form_validators import GlucoseFbgFormValidator
10
5
  from ..models import GlucoseFbg
11
6
 
12
7
 
13
- class GlucoseFbgFormValidator(CrfFormValidator):
14
- def clean(self):
15
- converted_value = None
16
- self.required_if(YES, field="fasting", field_required="fasting_duration_str")
17
- self.required_if(NO, field="fbg_performed", field_required="fbg_not_performed_reason")
18
- self.required_if(YES, field="fbg_performed", field_required="fbg_datetime")
19
- if self.cleaned_data.get("fbg_datetime") and self.cleaned_data.get(
20
- "fbg_datetime"
21
- ) < self.cleaned_data.get("report_datetime"):
22
- self.raise_validation_error(
23
- {"fbg_datetime": "Invalid. Must be on or after report date above"},
24
- INVALID_ERROR,
25
- )
26
- self.required_if(YES, field="fbg_performed", field_required="fbg_value")
27
- if self.cleaned_data.get("fbg_value") is not None:
28
- converted_value = validate_glucose_as_millimoles_per_liter(
29
- "fbg", self.cleaned_data
30
- )
31
-
32
- self.applicable_if(YES, field="fbg_performed", field_applicable="fbg_units")
33
-
34
- # repeat_fbg_date
35
- condition = converted_value and converted_value >= Decimal("7.0")
36
- self.required_if_true(condition, field_required="repeat_fbg_date")
37
- if self.cleaned_data.get("repeat_fbg_date") and self.cleaned_data.get("fbg_datetime"):
38
- diffdays = (
39
- self.cleaned_data.get("repeat_fbg_date")
40
- - self.cleaned_data.get("fbg_datetime").date()
41
- ).days
42
- if not (7 <= diffdays <= 10):
43
- self.raise_validation_error(
44
- {
45
- "repeat_fbg_date": (
46
- f"Must be 7 to 10 days from date measured above. Got {diffdays}."
47
- )
48
- },
49
- INVALID_ERROR,
50
- )
51
-
52
-
53
8
  class GlucoseFbgForm(CrfModelFormMixin, forms.ModelForm):
54
9
  form_validator_cls = GlucoseFbgFormValidator
55
10
 
@@ -1,2 +1,4 @@
1
1
  from .health_economics_simple_form import HealthEconomicsSimpleForm
2
2
  from .health_economics_update_form import HealthEconomicsUpdateForm
3
+
4
+ __all__ = ["HealthEconomicsSimpleForm", "HealthEconomicsUpdateForm"]
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import YES
1
2
  from django import forms
2
- from edc_constants.constants import YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
 
@@ -0,0 +1,13 @@
1
+ from django import forms
2
+ from edc_crf.modelform_mixins import CrfModelFormMixin
3
+
4
+ from ..form_validators import HivExitReviewFormValidator
5
+ from ..models import HivExitReview
6
+
7
+
8
+ class HivExitReviewForm(CrfModelFormMixin, forms.ModelForm):
9
+ form_validator_cls = HivExitReviewFormValidator
10
+
11
+ class Meta:
12
+ model = HivExitReview
13
+ fields = "__all__"
@@ -1,4 +1,4 @@
1
- from edc_constants.constants import NO, OTHER, YES
1
+ from clinicedc_constants import NO, OTHER, YES
2
2
 
3
3
 
4
4
  class ArvHistoryFormValidatorMixin:
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ from django import forms
4
+ from edc_appointment.form_validator_mixins import NextAppointmentCrfFormValidatorMixin
5
+ from edc_crf.crf_form_validator import CrfFormValidator
6
+ from edc_crf.modelform_mixins import CrfModelFormMixin
7
+
8
+ from ..models import NextAppointment
9
+
10
+ __all__ = ["NextAppointmentForm"]
11
+
12
+
13
+ class NextAppointmentCrfFormValidator(
14
+ NextAppointmentCrfFormValidatorMixin,
15
+ CrfFormValidator,
16
+ ):
17
+ pass
18
+
19
+
20
+ class NextAppointmentForm(CrfModelFormMixin, forms.ModelForm):
21
+ form_validator_cls = NextAppointmentCrfFormValidator
22
+
23
+ class Meta:
24
+ model = NextAppointment
25
+ fields = "__all__"
26
+ labels = { # noqa: RUF012
27
+ "appt_date": "Next scheduled appointment date",
28
+ "visitschedule": "Next scheduled appointment",
29
+ }
30
+ help_texts = { # noqa: RUF012
31
+ "appt_date": (
32
+ "Default recommended. If changed, should be within "
33
+ "the window period of the next appointment"
34
+ ),
35
+ "visitschedule": "Default recommended. Can only be the next visit",
36
+ }
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import YES
1
2
  from django import forms
2
- from edc_constants.constants import YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
  from edc_model_form.mixins import InlineModelFormMixin
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import NO, NONE, OTHER, YES
1
2
  from django import forms
2
- from edc_constants.constants import NO, NONE, OTHER, YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
 
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import YES
1
2
  from django import forms
2
- from edc_constants.constants import YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
 
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import YES
1
2
  from django import forms
2
- from edc_constants.constants import YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
 
@@ -22,4 +22,4 @@ class SliderWidget(Input):
22
22
  return context
23
23
 
24
24
  class Media:
25
- css = {"all": ("meta_subject/slider.css",)}
25
+ css = {"all": ("meta_subject/slider.css",)} # noqa: RUF012
@@ -1,6 +1,7 @@
1
1
  import re
2
2
 
3
3
  from django import forms
4
+ from django.core.exceptions import ObjectDoesNotExist
4
5
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
6
  from edc_form_validators import INVALID_ERROR
6
7
  from edc_pharmacy.form_validators import (
@@ -27,36 +28,41 @@ class StudyMedicationFormValidator(BaseStudyMedicationFormValidator):
27
28
  except AttributeError:
28
29
  self.raise_validation_error("Subject visit is required", INVALID_ERROR)
29
30
  else:
30
- if subject_visit.visit_code == DAY1 and subject_visit.visit_code_sequence == 0:
31
- if (
31
+ if (
32
+ subject_visit.visit_code == DAY1
33
+ and subject_visit.visit_code_sequence == 0
34
+ and (
32
35
  self.cleaned_data.get("dosage_guideline")
33
36
  and self.cleaned_data.get("dosage_guideline").dose != 1000
34
- ):
35
- raise forms.ValidationError(
36
- {"dosage_guideline": "Invalid. Expected 1000mg/day at baseline"}
37
- )
37
+ )
38
+ ):
39
+ raise forms.ValidationError(
40
+ {"dosage_guideline": "Invalid. Expected 1000mg/day at baseline"}
41
+ )
38
42
 
39
43
  def validate_stock_codes_are_dispensed(self):
40
44
  if self.cleaned_data.get("stock_codes"):
41
- pattern = re.compile("^([A-Z0-9]{6})(,[A-Z0-9]{6})*$")
45
+ # pattern = re.compile("^([A-Z0-9]{6})(,[A-Z0-9]{6})*$")
46
+ pattern = re.compile("^([A-Z0-9]{6})(\r\n[A-Z0-9]{6})*$")
42
47
  if not pattern.match(self.cleaned_data.get("stock_codes")):
43
48
  raise forms.ValidationError(
44
49
  {
45
50
  "stock_codes": (
46
- "Invalid format. Enter one or more valid codes separated by comma"
51
+ "Invalid format. Enter one or more valid codes. "
52
+ "One code per line only. No commas, spaces, etc"
47
53
  )
48
54
  }
49
55
  )
50
- for stock_code in self.cleaned_data.get("stock_codes").split(","):
56
+ for stock_code in self.cleaned_data.get("stock_codes").split("\r\n"):
51
57
  try:
52
58
  Stock.objects.get(
53
59
  code=stock_code,
54
- dispensed=True,
60
+ dispenseitem__isnull=False,
55
61
  allocation__registered_subject__subject_identifier=(
56
62
  self.subject_identifier
57
63
  ),
58
64
  )
59
- except Stock.DoesNotExist:
65
+ except ObjectDoesNotExist as e:
60
66
  raise forms.ValidationError(
61
67
  {
62
68
  "stock_codes": (
@@ -65,7 +71,7 @@ class StudyMedicationFormValidator(BaseStudyMedicationFormValidator):
65
71
  "Please check the bottle or check with your pharmacist."
66
72
  )
67
73
  }
68
- )
74
+ ) from e
69
75
 
70
76
 
71
77
  class StudyMedicationForm(CrfModelFormMixin, forms.ModelForm):
@@ -20,7 +20,7 @@ class SubjectRequisitionForm(RequisitionModelFormMixin, forms.ModelForm):
20
20
  cleaned_data = super().clean()
21
21
  if cleaned_data.get("reason_not_drawn") == NOT_REQUIRED:
22
22
  raise forms.ValidationError(
23
- {"reason_not_drawn": "Invalid choice. Not expected " "for this panel"}
23
+ {"reason_not_drawn": "Invalid choice. Not expected for this panel"}
24
24
  )
25
25
  return cleaned_data
26
26
 
@@ -1,5 +1,5 @@
1
+ from clinicedc_constants import NO, NOT_APPLICABLE, OTHER, YES
1
2
  from django import forms
2
- from edc_constants.constants import NO, NOT_APPLICABLE, OTHER, YES
3
3
  from edc_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
  from edc_form_validators import INVALID_ERROR
@@ -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_crf.crf_form_validator import CrfFormValidator
4
4
  from edc_crf.modelform_mixins import CrfModelFormMixin
5
5
 
@@ -1,6 +1,6 @@
1
+ from clinicedc_constants import NO, YES
1
2
  from django import forms
2
3
  from edc_action_item.forms import ActionItemCrfFormMixin
3
- from edc_constants.constants import NO, YES
4
4
  from edc_crf.crf_form_validator import CrfFormValidator
5
5
  from edc_crf.modelform_mixins import CrfModelFormMixin
6
6
  from edc_form_validators import INVALID_ERROR
@@ -39,14 +39,14 @@ def create_missing_rx_refills():
39
39
  print_messages(messages)
40
40
 
41
41
 
42
- def save_or_raise(obj, messages: list[str] = None):
42
+ def save_or_raise(obj, messages: list[str] | None = None):
43
43
  try:
44
44
  obj.save()
45
45
  except NextStudyMedicationError as e:
46
46
  messages.append(f"NextStudyMedicationError: {e}")
47
47
  except ObjectDoesNotExist as e:
48
48
  messages.append(
49
- f"ObjectDoesNotExist: {obj.subject_identifier}, {obj.related_visit}, {str(e)}"
49
+ f"ObjectDoesNotExist: {obj.subject_identifier}, {obj.related_visit}, {e!s}"
50
50
  )
51
51
  except StudyMedicationError as e:
52
52
  messages.append(f"StudyMedicationError: {e}")
@@ -65,5 +65,5 @@ def print_messages(messages: list[str]):
65
65
 
66
66
 
67
67
  class Command(BaseCommand):
68
- def handle(self, *args, **options):
68
+ def handle(self, *args, **options): # noqa: ARG002
69
69
  create_missing_rx_refills()
@@ -27,7 +27,7 @@ def create_missing_rx():
27
27
  subject_identifier=subject_consent.subject_identifier,
28
28
  report_datetime=subject_consent.consent_datetime,
29
29
  randomizer_name=get_meta_version(),
30
- medications=[METFORMIN],
30
+ medication_names=[METFORMIN],
31
31
  site=subject_consent.site,
32
32
  )
33
33
  except PrescriptionAlreadyExists:
@@ -39,5 +39,5 @@ def create_missing_rx():
39
39
 
40
40
 
41
41
  class Command(BaseCommand):
42
- def handle(self, *args, **options):
42
+ def handle(self, *args, **options): # noqa: ARG002
43
43
  create_missing_rx()