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,235 @@
1
+ # Generated by Django 5.2.6 on 2025-09-29 21:51
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("meta_prn", "0067_alter_offschedule_managers_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="dmreferral",
15
+ name="referral_note",
16
+ field=models.TextField(
17
+ default="",
18
+ verbose_name="Please provide a brief history of the diabetes diagnosis that lead to this referral",
19
+ ),
20
+ ),
21
+ migrations.AlterField(
22
+ model_name="endofstudy",
23
+ name="clinical_withdrawal_investigator_decision",
24
+ field=models.TextField(
25
+ blank=True,
26
+ default="",
27
+ max_length=500,
28
+ verbose_name="If withdrawl was an 'investigator decision', please explain ...",
29
+ ),
30
+ ),
31
+ migrations.AlterField(
32
+ model_name="endofstudy",
33
+ name="clinical_withdrawal_reason_other",
34
+ field=models.TextField(
35
+ blank=True,
36
+ default="",
37
+ max_length=500,
38
+ verbose_name="If withdrawn for 'other' condition, please explain",
39
+ ),
40
+ ),
41
+ migrations.AlterField(
42
+ model_name="endofstudy",
43
+ name="comment",
44
+ field=models.TextField(
45
+ blank=True,
46
+ default="",
47
+ max_length=500,
48
+ verbose_name="Please provide further details if possible",
49
+ ),
50
+ ),
51
+ migrations.AlterField(
52
+ model_name="endofstudy",
53
+ name="other_offstudy_reason",
54
+ field=models.TextField(
55
+ blank=True,
56
+ default="",
57
+ max_length=500,
58
+ verbose_name="If OTHER, please specify",
59
+ ),
60
+ ),
61
+ migrations.AlterField(
62
+ model_name="endofstudy",
63
+ name="toxicity_withdrawal_reason_other",
64
+ field=models.TextField(
65
+ blank=True,
66
+ default="",
67
+ max_length=500,
68
+ verbose_name="If 'other toxicity', please specify ...",
69
+ ),
70
+ ),
71
+ migrations.AlterField(
72
+ model_name="historicaldmreferral",
73
+ name="referral_note",
74
+ field=models.TextField(
75
+ default="",
76
+ verbose_name="Please provide a brief history of the diabetes diagnosis that lead to this referral",
77
+ ),
78
+ ),
79
+ migrations.AlterField(
80
+ model_name="historicalendofstudy",
81
+ name="clinical_withdrawal_investigator_decision",
82
+ field=models.TextField(
83
+ blank=True,
84
+ default="",
85
+ max_length=500,
86
+ verbose_name="If withdrawl was an 'investigator decision', please explain ...",
87
+ ),
88
+ ),
89
+ migrations.AlterField(
90
+ model_name="historicalendofstudy",
91
+ name="clinical_withdrawal_reason_other",
92
+ field=models.TextField(
93
+ blank=True,
94
+ default="",
95
+ max_length=500,
96
+ verbose_name="If withdrawn for 'other' condition, please explain",
97
+ ),
98
+ ),
99
+ migrations.AlterField(
100
+ model_name="historicalendofstudy",
101
+ name="comment",
102
+ field=models.TextField(
103
+ blank=True,
104
+ default="",
105
+ max_length=500,
106
+ verbose_name="Please provide further details if possible",
107
+ ),
108
+ ),
109
+ migrations.AlterField(
110
+ model_name="historicalendofstudy",
111
+ name="other_offstudy_reason",
112
+ field=models.TextField(
113
+ blank=True,
114
+ default="",
115
+ max_length=500,
116
+ verbose_name="If OTHER, please specify",
117
+ ),
118
+ ),
119
+ migrations.AlterField(
120
+ model_name="historicalendofstudy",
121
+ name="toxicity_withdrawal_reason_other",
122
+ field=models.TextField(
123
+ blank=True,
124
+ default="",
125
+ max_length=500,
126
+ verbose_name="If 'other toxicity', please specify ...",
127
+ ),
128
+ ),
129
+ migrations.AlterField(
130
+ model_name="historicallosstofollowup",
131
+ name="comment",
132
+ field=models.TextField(
133
+ default="",
134
+ verbose_name="Please give details of the circumstances that have led to this decision.",
135
+ ),
136
+ ),
137
+ migrations.AlterField(
138
+ model_name="historicallosstofollowup",
139
+ name="home_visit_detail",
140
+ field=models.TextField(
141
+ default="",
142
+ verbose_name="If YES, provide any further details of the home visit",
143
+ ),
144
+ ),
145
+ migrations.AlterField(
146
+ model_name="historicaloffstudymedication",
147
+ name="comment",
148
+ field=models.TextField(
149
+ blank=True, default="", verbose_name="Any additional comments"
150
+ ),
151
+ ),
152
+ migrations.AlterField(
153
+ model_name="historicaloffstudymedication",
154
+ name="reason_other",
155
+ field=models.TextField(
156
+ blank=True, default="", verbose_name="If other, please specify ..."
157
+ ),
158
+ ),
159
+ migrations.AlterField(
160
+ model_name="historicalpregnancynotification",
161
+ name="unconfirmed_details",
162
+ field=models.TextField(
163
+ blank=True, default="", verbose_name="If no, please provide details"
164
+ ),
165
+ ),
166
+ migrations.AlterField(
167
+ model_name="historicalprotocolincident",
168
+ name="action_required_old",
169
+ field=models.CharField(
170
+ choices=[
171
+ ("remain_on_study", "Participant to remain on trial"),
172
+ ("to_be_withdrawn", "Participant to be withdrawn from trial"),
173
+ (
174
+ "remain_on_study_modified",
175
+ "Patient remains on study but data analysis will be modified",
176
+ ),
177
+ ],
178
+ default="",
179
+ max_length=45,
180
+ ),
181
+ ),
182
+ migrations.AlterField(
183
+ model_name="losstofollowup",
184
+ name="comment",
185
+ field=models.TextField(
186
+ default="",
187
+ verbose_name="Please give details of the circumstances that have led to this decision.",
188
+ ),
189
+ ),
190
+ migrations.AlterField(
191
+ model_name="losstofollowup",
192
+ name="home_visit_detail",
193
+ field=models.TextField(
194
+ default="",
195
+ verbose_name="If YES, provide any further details of the home visit",
196
+ ),
197
+ ),
198
+ migrations.AlterField(
199
+ model_name="offstudymedication",
200
+ name="comment",
201
+ field=models.TextField(
202
+ blank=True, default="", verbose_name="Any additional comments"
203
+ ),
204
+ ),
205
+ migrations.AlterField(
206
+ model_name="offstudymedication",
207
+ name="reason_other",
208
+ field=models.TextField(
209
+ blank=True, default="", verbose_name="If other, please specify ..."
210
+ ),
211
+ ),
212
+ migrations.AlterField(
213
+ model_name="pregnancynotification",
214
+ name="unconfirmed_details",
215
+ field=models.TextField(
216
+ blank=True, default="", verbose_name="If no, please provide details"
217
+ ),
218
+ ),
219
+ migrations.AlterField(
220
+ model_name="protocolincident",
221
+ name="action_required_old",
222
+ field=models.CharField(
223
+ choices=[
224
+ ("remain_on_study", "Participant to remain on trial"),
225
+ ("to_be_withdrawn", "Participant to be withdrawn from trial"),
226
+ (
227
+ "remain_on_study_modified",
228
+ "Patient remains on study but data analysis will be modified",
229
+ ),
230
+ ],
231
+ default="",
232
+ max_length=45,
233
+ ),
234
+ ),
235
+ ]
@@ -0,0 +1,37 @@
1
+ # Generated by Django 5.2.7 on 2025-10-01 14:33
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("meta_prn", "0068_alter_dmreferral_referral_note_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="historicaloffstudymedication",
15
+ name="singleton_field",
16
+ field=models.CharField(
17
+ db_index=True,
18
+ default="",
19
+ editable=False,
20
+ help_text="auto updated for unique constraint",
21
+ max_length=50,
22
+ verbose_name="subject identifier",
23
+ ),
24
+ ),
25
+ migrations.AlterField(
26
+ model_name="offstudymedication",
27
+ name="singleton_field",
28
+ field=models.CharField(
29
+ default="",
30
+ editable=False,
31
+ help_text="auto updated for unique constraint",
32
+ max_length=50,
33
+ unique=True,
34
+ verbose_name="subject identifier",
35
+ ),
36
+ ),
37
+ ]
@@ -21,3 +21,23 @@ from .signals import (
21
21
  update_urine_pregnancy_on_pregnancy_notification_on_post_save,
22
22
  )
23
23
  from .subject_transfer import SubjectTransfer
24
+
25
+ __all__ = [
26
+ "DmReferral",
27
+ "EndOfStudy",
28
+ "LossToFollowup",
29
+ "OffSchedule",
30
+ "OffScheduleDmReferral",
31
+ "OffSchedulePostnatal",
32
+ "OffSchedulePregnancy",
33
+ "OffStudyMedication",
34
+ "OnSchedule",
35
+ "OnScheduleDmReferral",
36
+ "OnSchedulePostnatal",
37
+ "OnSchedulePregnancy",
38
+ "PregnancyNotification",
39
+ "ProtocolIncident",
40
+ "SubjectTransfer",
41
+ "update_schedule_on_pregnancy_notification_post_save",
42
+ "update_urine_pregnancy_on_pregnancy_notification_on_post_save",
43
+ ]
@@ -1,3 +1,4 @@
1
+ from clinicedc_constants import NULL_STRING
1
2
  from django.db import models
2
3
  from edc_action_item.models import ActionModelMixin
3
4
  from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
@@ -14,7 +15,6 @@ class DmReferral(
14
15
  UniqueSubjectIdentifierFieldMixin,
15
16
  BaseUuidModel,
16
17
  ):
17
-
18
18
  action_name = DM_REFFERAL_ACTION
19
19
 
20
20
  report_datetime = models.DateTimeField(
@@ -30,7 +30,7 @@ class DmReferral(
30
30
  "Please provide a brief history of the "
31
31
  "diabetes diagnosis that lead to this referral"
32
32
  ),
33
- null=True,
33
+ default=NULL_STRING,
34
34
  blank=False,
35
35
  )
36
36
 
@@ -1,16 +1,17 @@
1
- from django.db import models
2
- from edc_action_item.models import ActionModelMixin
3
- from edc_constants.choices import YES_NO_NA
4
- from edc_constants.constants import (
1
+ from clinicedc_constants import (
5
2
  DEAD,
6
3
  DELIVERY,
7
4
  DIABETES,
5
+ LTFU,
8
6
  NOT_APPLICABLE,
7
+ NULL_STRING,
9
8
  OTHER,
10
9
  PREGNANCY,
11
10
  TOXICITY,
12
11
  )
13
- from edc_ltfu.constants import LOST_TO_FOLLOWUP
12
+ from django.db import models
13
+ from edc_action_item.models import ActionModelMixin
14
+ from edc_constants.choices import YES_NO_NA
14
15
  from edc_model.models import BaseUuidModel
15
16
  from edc_model.validators import date_not_future
16
17
  from edc_offstudy.constants import (
@@ -26,18 +27,18 @@ from edc_transfer.constants import TRANSFERRED
26
27
  from meta_lists.models import OffstudyReasons
27
28
 
28
29
  from ..choices import CLINICAL_WITHDRAWAL_REASONS, TOXICITY_WITHDRAWAL_REASONS
30
+ from ..constants import CLINICAL_WITHDRAWAL, COMPLETED_FOLLOWUP_48
29
31
 
30
32
  # TODO: confirm all appointments are either new, incomplete or done
31
33
  # TODO: take off study meds but coninue followup (WITHDRAWAL)
32
34
  # TODO: follow on new schedule, if permanently off drug (Single 36m visit)
33
- from ..constants import CLINICAL_WITHDRAWAL
35
+
36
+ # TODO: add label for "End of followup as per protocol FEB2026"
34
37
 
35
38
 
36
39
  class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidModel):
37
40
  action_name = END_OF_STUDY_ACTION
38
41
 
39
- tracking_identifier_prefix = "ST"
40
-
41
42
  last_seen_date = models.DateField(
42
43
  verbose_name="Date patient was last seen",
43
44
  validators=[date_not_future],
@@ -52,24 +53,28 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
52
53
  null=True,
53
54
  limit_choices_to={
54
55
  "name__in": [
55
- CLINICAL_WITHDRAWAL,
56
56
  COMPLETED_FOLLOWUP,
57
- DEAD,
58
- DELIVERY,
57
+ COMPLETED_FOLLOWUP_48,
59
58
  DIABETES,
60
- LATE_EXCLUSION,
61
- LOST_TO_FOLLOWUP,
62
- OTHER,
59
+ DELIVERY,
63
60
  PREGNANCY,
61
+ CLINICAL_WITHDRAWAL,
62
+ DEAD,
63
+ LTFU,
64
64
  TOXICITY,
65
65
  TRANSFERRED,
66
66
  WITHDRAWAL,
67
+ LATE_EXCLUSION,
68
+ OTHER,
67
69
  ]
68
70
  },
69
71
  )
70
72
 
71
73
  other_offstudy_reason = models.TextField(
72
- verbose_name="If OTHER, please specify", max_length=500, blank=True, null=True
74
+ verbose_name="If OTHER, please specify",
75
+ max_length=500,
76
+ blank=True,
77
+ default=NULL_STRING,
73
78
  )
74
79
 
75
80
  # TODO: 6m off drug and duration ?? See SOP
@@ -95,8 +100,9 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
95
100
  blank=True,
96
101
  null=True,
97
102
  help_text=(
98
- "A UPT CRF must be on file and participant not on the delivery schedule. "
99
- "Use UPT date or, if UPT not needed, use report date on last UPT CRF."
103
+ "A UPT CRF must be on file and participant not on the "
104
+ "delivery schedule. Use UPT date or, if UPT not needed, "
105
+ "use report date on last UPT CRF."
100
106
  ),
101
107
  )
102
108
 
@@ -113,8 +119,7 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
113
119
 
114
120
  clinical_withdrawal_reason = models.CharField(
115
121
  verbose_name=(
116
- "If the patient was withdrawn on CLINICAL grounds, "
117
- "please specify PRIMARY reason"
122
+ "If the patient was withdrawn on CLINICAL grounds, please specify PRIMARY reason"
118
123
  ),
119
124
  max_length=25,
120
125
  choices=CLINICAL_WITHDRAWAL_REASONS,
@@ -125,14 +130,14 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
125
130
  verbose_name="If withdrawn for 'other' condition, please explain",
126
131
  max_length=500,
127
132
  blank=True,
128
- null=True,
133
+ default=NULL_STRING,
129
134
  )
130
135
 
131
136
  clinical_withdrawal_investigator_decision = models.TextField(
132
137
  verbose_name="If withdrawl was an 'investigator decision', please explain ...",
133
138
  max_length=500,
134
139
  blank=True,
135
- null=True,
140
+ default=NULL_STRING,
136
141
  )
137
142
 
138
143
  toxicity_withdrawal_reason = models.CharField(
@@ -146,7 +151,7 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
146
151
  verbose_name="If 'other toxicity', please specify ...",
147
152
  max_length=500,
148
153
  blank=True,
149
- null=True,
154
+ default=NULL_STRING,
150
155
  )
151
156
 
152
157
  transfer_date = models.DateField(
@@ -168,7 +173,7 @@ class EndOfStudy(ActionModelMixin, SiteModelMixin, OffstudyModelMixin, BaseUuidM
168
173
  verbose_name="Please provide further details if possible",
169
174
  max_length=500,
170
175
  blank=True,
171
- null=True,
176
+ default=NULL_STRING,
172
177
  )
173
178
 
174
179
  class Meta(OffstudyModelMixin.Meta):
@@ -1,8 +1,8 @@
1
+ from clinicedc_constants import NULL_STRING, OTHER
1
2
  from django.db import models
2
3
  from edc_action_item.models.action_model_mixin import ActionModelMixin
3
4
  from edc_constants.choices import YES_NO
4
- from edc_constants.constants import OTHER
5
- from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
5
+ from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
6
6
  from edc_ltfu.constants import LTFU_ACTION
7
7
  from edc_model.models import BaseUuidModel, OtherCharField
8
8
  from edc_sites.model_mixins import SiteModelMixin
@@ -19,13 +19,11 @@ LOSS_CHOICES = (
19
19
  class LossToFollowup(
20
20
  ActionModelMixin,
21
21
  SiteModelMixin,
22
- NonUniqueSubjectIdentifierFieldMixin,
22
+ UniqueSubjectIdentifierFieldMixin,
23
23
  BaseUuidModel,
24
24
  ):
25
25
  action_name = LTFU_ACTION
26
26
 
27
- tracking_identifier_prefix = "LF"
28
-
29
27
  report_datetime = models.DateTimeField(
30
28
  verbose_name="Report Date and Time", default=get_utcnow
31
29
  )
@@ -50,7 +48,7 @@ class LossToFollowup(
50
48
 
51
49
  home_visit_detail = models.TextField(
52
50
  verbose_name="If YES, provide any further details of the home visit",
53
- null=True,
51
+ default=NULL_STRING,
54
52
  blank=False,
55
53
  )
56
54
 
@@ -66,13 +64,13 @@ class LossToFollowup(
66
64
  verbose_name=(
67
65
  "Please give details of the circumstances that have led to this decision."
68
66
  ),
69
- null=True,
67
+ default=NULL_STRING,
70
68
  blank=False,
71
69
  )
72
70
 
73
71
  class Meta(BaseUuidModel.Meta):
74
72
  verbose_name = "Loss to Follow Up"
75
73
  verbose_name_plural = "Loss to Follow Up"
76
- indexes = [
77
- models.Index(fields=["subject_identifier", "action_identifier", "site", "id"])
78
- ]
74
+ indexes = (
75
+ models.Index(fields=("subject_identifier", "action_identifier", "site", "id")),
76
+ )
@@ -1,8 +1,10 @@
1
+ from clinicedc_constants import NULL_STRING
1
2
  from django.db import models
2
3
  from edc_action_item.models import ActionModelMixin
3
- from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
4
+ from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
4
5
  from edc_model.models import BaseUuidModel
5
6
  from edc_pharmacy.models import Medication
7
+ from edc_prn.models import SingletonPrnModelMixin
6
8
  from edc_sites.model_mixins import SiteModelMixin
7
9
  from edc_utils import get_utcnow
8
10
 
@@ -13,9 +15,10 @@ from ..constants import OFFSTUDY_MEDICATION_ACTION
13
15
 
14
16
 
15
17
  class OffStudyMedication(
16
- NonUniqueSubjectIdentifierFieldMixin,
18
+ UniqueSubjectIdentifierFieldMixin,
17
19
  SiteModelMixin,
18
20
  ActionModelMixin,
21
+ SingletonPrnModelMixin,
19
22
  BaseUuidModel,
20
23
  ):
21
24
  action_name = OFFSTUDY_MEDICATION_ACTION
@@ -44,13 +47,13 @@ class OffStudyMedication(
44
47
 
45
48
  reason_other = models.TextField(
46
49
  verbose_name="If other, please specify ...",
47
- null=True,
50
+ default=NULL_STRING,
48
51
  blank=True,
49
52
  )
50
53
 
51
54
  comment = models.TextField(
52
55
  verbose_name="Any additional comments",
53
- null=True,
56
+ default=NULL_STRING,
54
57
  blank=True,
55
58
  )
56
59
 
@@ -11,7 +11,7 @@ from ..constants import (
11
11
  )
12
12
 
13
13
 
14
- class OffSchedule(SiteModelMixin, ActionModelMixin, OffScheduleModelMixin, BaseUuidModel):
14
+ class OffSchedule(SiteModelMixin, OffScheduleModelMixin, ActionModelMixin, BaseUuidModel):
15
15
  action_name = OFFSCHEDULE_ACTION
16
16
  offschedule_compare_dates_as_datetimes = False
17
17
 
@@ -21,7 +21,7 @@ class OffSchedule(SiteModelMixin, ActionModelMixin, OffScheduleModelMixin, BaseU
21
21
 
22
22
 
23
23
  class OffSchedulePregnancy(
24
- SiteModelMixin, ActionModelMixin, OffScheduleModelMixin, BaseUuidModel
24
+ SiteModelMixin, OffScheduleModelMixin, ActionModelMixin, BaseUuidModel
25
25
  ):
26
26
  action_name = OFFSCHEDULE_PREGNANCY_ACTION
27
27
 
@@ -31,7 +31,7 @@ class OffSchedulePregnancy(
31
31
 
32
32
 
33
33
  class OffSchedulePostnatal(
34
- SiteModelMixin, ActionModelMixin, OffScheduleModelMixin, BaseUuidModel
34
+ SiteModelMixin, OffScheduleModelMixin, ActionModelMixin, BaseUuidModel
35
35
  ):
36
36
  action_name = OFFSCHEDULE_POSTNATAL_ACTION
37
37
 
@@ -41,7 +41,7 @@ class OffSchedulePostnatal(
41
41
 
42
42
 
43
43
  class OffScheduleDmReferral(
44
- SiteModelMixin, ActionModelMixin, OffScheduleModelMixin, BaseUuidModel
44
+ SiteModelMixin, OffScheduleModelMixin, ActionModelMixin, BaseUuidModel
45
45
  ):
46
46
  action_name = OFFSCHEDULE_DM_REFERRAL_ACTION
47
47
 
@@ -1,7 +1,7 @@
1
+ from clinicedc_constants import NULL_STRING, YES
1
2
  from django.db import models
2
3
  from edc_action_item.models import ActionModelMixin
3
4
  from edc_constants.choices import YES_NO, YES_NO_UNSURE
4
- from edc_constants.constants import YES
5
5
  from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
6
6
  from edc_model.models import BaseUuidModel
7
7
  from edc_sites.model_mixins import SiteModelMixin
@@ -24,8 +24,6 @@ class PregnancyNotification(
24
24
  ):
25
25
  action_name = PREGNANCY_NOTIFICATION_ACTION
26
26
 
27
- tracking_identifier_prefix = "PN"
28
-
29
27
  report_datetime = models.DateTimeField(
30
28
  verbose_name="Report Date and Time", default=get_utcnow
31
29
  )
@@ -46,7 +44,7 @@ class PregnancyNotification(
46
44
 
47
45
  unconfirmed_details = models.TextField(
48
46
  verbose_name="If no, please provide details",
49
- null=True,
47
+ default=NULL_STRING,
50
48
  blank=True,
51
49
  )
52
50
 
@@ -99,4 +97,4 @@ class PregnancyNotification(
99
97
  class Meta(BaseUuidModel.Meta):
100
98
  verbose_name = "Pregnancy Notification"
101
99
  verbose_name_plural = "Pregnancy Notifications"
102
- unique_together = ["subject_identifier", "edd"]
100
+ unique_together = ("subject_identifier", "edd")
@@ -1,3 +1,4 @@
1
+ from clinicedc_constants import NULL_STRING
1
2
  from django.db import models
2
3
  from edc_action_item.models import ActionItem, ActionModelMixin
3
4
  from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
@@ -26,10 +27,12 @@ class ProtocolIncident(
26
27
  related_name="meta_prn_action_item",
27
28
  )
28
29
 
29
- action_required_old = models.CharField(max_length=45, choices=ACTION_REQUIRED, null=True)
30
+ action_required_old = models.CharField(
31
+ max_length=45, choices=ACTION_REQUIRED, default=NULL_STRING
32
+ )
30
33
 
31
34
  def natural_key(self):
32
- return (self.action_identifier,) # noqa
35
+ return (self.action_identifier,)
33
36
 
34
37
  class Meta(ProtocolIncidentModelMixin.Meta, BaseUuidModel.Meta):
35
38
  pass