meta-edc 1.0.3__py3-none-any.whl → 1.0.4__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 (31) hide show
  1. meta_analytics/dataframes/get_eos_df.py +1 -1
  2. meta_analytics/dataframes/get_last_imp_visits_df.py +5 -2
  3. meta_analytics/dataframes/screening/get_screening_df.py +2 -1
  4. meta_edc/settings/debug.py +2 -2
  5. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/METADATA +3 -3
  6. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/RECORD +31 -20
  7. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/WHEEL +1 -1
  8. meta_lists/list_data.py +4 -0
  9. meta_lists/migrations/0019_auto_20250128_0143.py +48 -0
  10. meta_subject/action_items.py +8 -1
  11. meta_subject/admin/__init__.py +1 -0
  12. meta_subject/admin/next_appointment_admin.py +20 -0
  13. meta_subject/forms/__init__.py +1 -0
  14. meta_subject/forms/next_appointment_form.py +37 -0
  15. meta_subject/metadata_rules/metadata_rules.py +14 -0
  16. meta_subject/metadata_rules/predicates.py +29 -3
  17. meta_subject/migrations/0216_historicalnextappointment_nextappointment.py +554 -0
  18. meta_subject/migrations/0217_alter_historicalnextappointment_appt_datetime_and_more.py +42 -0
  19. meta_subject/migrations/0218_alter_historicalnextappointment_appt_date_and_more.py +53 -0
  20. meta_subject/migrations/0219_remove_historicalnextappointment_allow_create_interim_and_more.py +92 -0
  21. meta_subject/migrations/0220_historicalbloodresultsgludummy_bloodresultsgludummy.py +834 -0
  22. meta_subject/models/__init__.py +2 -0
  23. meta_subject/models/blood_results/__init__.py +1 -0
  24. meta_subject/models/blood_results/blood_results_glu.py +29 -0
  25. meta_subject/models/next_appointment.py +16 -0
  26. meta_subject/tests/tests/test_next_appointment.py +231 -0
  27. meta_visit_schedule/visit_schedules/phase_three/crfs.py +20 -1
  28. meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py +1 -1
  29. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/AUTHORS +0 -0
  30. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/LICENSE +0 -0
  31. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ def get_eos_df() -> pd.DataFrame:
14
14
  df_visit = get_subject_visit("meta_subject.subjectvisit")
15
15
  df_last_visit = (
16
16
  df_visit.groupby(["subject_identifier", "site"])
17
- .agg({"last_visit_code": "max", "last_visit_datetime": "max"})
17
+ .agg({"endline_visit_code": "max", "endline_visit_datetime": "max"})
18
18
  .reset_index()
19
19
  )
20
20
  df_last_visit = df_last_visit.rename(columns={"site": "site_id"})
@@ -37,11 +37,14 @@ def get_last_imp_visits_df(
37
37
  df_meds = (
38
38
  df_meds[(df_meds.refill == "Yes") & (site_cond(df_meds, site_id))]
39
39
  .groupby(by=["subject_identifier", "site_id"])
40
- .agg({"last_visit_code": "max", "last_visit_datetime": "max"})
40
+ .agg({"endline_visit_code": "max", "endline_visit_datetime": "max"})
41
41
  .reset_index()
42
42
  )
43
43
  df_meds = df_meds.rename(
44
- columns={"last_visit_code": "imp_visit_code", "last_visit_datetime": "imp_visit_date"}
44
+ columns={
45
+ "endline_visit_code": "imp_visit_code",
46
+ "endline_visit_datetime": "imp_visit_date",
47
+ }
45
48
  )
46
49
  df_meds.reset_index()
47
50
 
@@ -110,7 +110,8 @@ def get_screening_df(df: pd.DataFrame | None = None) -> pd.DataFrame:
110
110
 
111
111
  # bmi
112
112
  # subject SR9E8B4D has eligible part two == No but subject has a glucose value
113
- df.loc[(df["screening_identifier"] == "SR9E8B4D"), "eligible_part_two"] = "Yes"
113
+ # NOTE: update 10-02-2025: subject is not eligible by congestive_heart_failure
114
+ # df.loc[(df["screening_identifier"] == "SR9E8B4D"), "eligible_part_two"] = "Yes"
114
115
 
115
116
  # merge with physical exam to get waist circumference if taken at baseline
116
117
  subject_identifiers = list(df["subject_identifier"])
@@ -7,11 +7,11 @@ from .defaults import * # noqa
7
7
  print(f"Settings file {__file__}")
8
8
 
9
9
  # TZ Sites:
10
- SITE_ID = SiteID(default=20) # Amana
10
+ # SITE_ID = SiteID(default=20) # Amana
11
11
  # SITE_ID = SiteID(default=10) # Hindu Mandal
12
12
  # SITE_ID = SiteID(default=40) # Mwananyamala
13
13
  # SITE_ID = SiteID(default=50) # Mbagala
14
- # SITE_ID = SiteID(default=60) # Mnazi-Moja
14
+ SITE_ID = SiteID(default=60) # Mnazi-Moja
15
15
  # SITE_ID = SiteID(default=30) # Temeke
16
16
  INDEX_PAGE = "http://localhost:8000"
17
17
  EDC_SITES_UAT_DOMAIN = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: meta-edc
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: META Trial EDC (http://www.isrctn.com/ISRCTN76157257)
5
5
  Home-page: https://github.com/meta-trial/meta-edc
6
6
  Author: Erik van Widenfelt
@@ -693,7 +693,7 @@ Requires-Python: >=3.12
693
693
  Description-Content-Type: text/x-rst
694
694
  License-File: LICENSE
695
695
  License-File: AUTHORS
696
- Requires-Dist: edc==1.0.2
696
+ Requires-Dist: edc==1.0.5
697
697
  Requires-Dist: edc-microscopy
698
698
  Requires-Dist: beautifulsoup4
699
699
  Requires-Dist: celery[redis]
@@ -712,7 +712,7 @@ Metformin treatment in Africa- META
712
712
  * https://www.lstmed.ac.uk/research/departments/international-public-health/respond-africa/meta
713
713
  * http://www.isrctn.com/ISRCTN76157257
714
714
 
715
- py 3.12 / DJ 5.1 / edc 0.6.0 (META3)
715
+ py 3.12 / DJ 5.1.5 / edc 1.0.3 (META3)
716
716
 
717
717
  This codebase is used for two randomized clinical trials:
718
718
 
@@ -87,8 +87,8 @@ meta_analytics/constants.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
87
  meta_analytics/get_tables.py,sha256=3jFmvLXWHY3FPd1u5OPVpAKWUcruCH0-A0KdKiiFGpc,2219
88
88
  meta_analytics/dataframes/__init__.py,sha256=DHO81CYc5foDgy2HBEnlaHRtohMo-blvSvZPMDQaHUk,547
89
89
  meta_analytics/dataframes/constants.py,sha256=Wcub_3U5xHa027ykotySiUxMECjmswGIADVeT0iJXXs,792
90
- meta_analytics/dataframes/get_eos_df.py,sha256=YJ0YB93FkqwpNfWDphzFbX6B7BannbvfScc0WEgtn2w,778
91
- meta_analytics/dataframes/get_last_imp_visits_df.py,sha256=ROBsYzJvlmSk86jA35dq-hK-2r7Nh6XSyAY8m1Zl93Q,3756
90
+ meta_analytics/dataframes/get_eos_df.py,sha256=quWdYsgwna9wfJ8GJPiiNLreRIrD4lY9BkFNAAjb2ds,784
91
+ meta_analytics/dataframes/get_last_imp_visits_df.py,sha256=cScwy_nBGHg04_AYpjz_pTq13Q4iyb33SiKk6CltbyQ,3803
92
92
  meta_analytics/dataframes/utils.py,sha256=2V3nFFnaysuJvNrcHUOLqOk8e_3aP71079kB_YBXcQw,2014
93
93
  meta_analytics/dataframes/enrolled/__init__.py,sha256=uKniE7L86umlSmGOjAFuwwsbyZj31mELGUpY3hByo4s,43
94
94
  meta_analytics/dataframes/enrolled/get_glucose_df.py,sha256=L4gzszNjYzu-QmYu4gs1c7_Edcv7FgAjucihxHtANSY,5004
@@ -97,7 +97,7 @@ meta_analytics/dataframes/glucose_endpoints/endpoint_by_date.py,sha256=aOadsfecl
97
97
  meta_analytics/dataframes/glucose_endpoints/glucose_endpoints_by_date.py,sha256=052BpLJoJezjr2tMXI5-GBRk_e6gT0bZZsjhx_Uhlm8,21550
98
98
  meta_analytics/dataframes/screening/__init__.py,sha256=onGpmB4474gu_JcyRGdRy09YQyP2Np-mX-rYZTFdJoA,114
99
99
  meta_analytics/dataframes/screening/get_glucose_tested_only_df.py,sha256=0oMJIsIJRjurfpPONuJ4Aoab1UJikezGe3lQNWRoOo4,660
100
- meta_analytics/dataframes/screening/get_screening_df.py,sha256=VS3fjpQcD_CdRT2MRx2MUU6xqpYL1fMYFvKNvZsvrro,6188
100
+ meta_analytics/dataframes/screening/get_screening_df.py,sha256=t_xxr7YId3QsXbwjPpi7nIgkleKprmZSqAin2cuB2Vc,6273
101
101
  meta_analytics/notebooks/cleaning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  meta_analytics/tables/__init__.py,sha256=mhESCt0Lq4RJU-lbQ5fVfIbXzrEsootGYp7EzQIqDBI,70
103
103
  meta_analytics/tables/eligible.py,sha256=2q-SMbAsrBgOVc4Ttq5P3bpjsUKwP5hYhJBMgyH6GGI,3389
@@ -247,7 +247,7 @@ meta_edc/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
247
247
  meta_edc/management/commands/update_forms_reference.py,sha256=jvCU9YdMtp9wbmjqKQsB9gxNw4DcAP97sZD-kfIxOns,1071
248
248
  meta_edc/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
249
  meta_edc/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
250
- meta_edc/settings/debug.py,sha256=ys60bSDcEMbWewoTdE4HRIp2woOwy3RPjIgXMUCEJpQ,1296
250
+ meta_edc/settings/debug.py,sha256=5WkxxapNtYDi9XKXCOCnlZ3q9--zktBtRyGhCVUaMEs,1296
251
251
  meta_edc/settings/defaults.py,sha256=YBOFTG7k9ESeOD_DUx6vdK6ewncTtPwnZFQTdSP_WAk,19614
252
252
  meta_edc/settings/live.py,sha256=uLTlsIc3H6gdE_7pkL6vyOVa6V_74hnXFkiojqGFAYY,264
253
253
  meta_edc/settings/logging.py,sha256=6qVUE37OMkf5rzwTmMq4krFsZ2jcyCpWdFtGih_Cs4U,1938
@@ -280,7 +280,7 @@ meta_lists/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
280
  meta_lists/admin.py,sha256=g05vpXfVIEBVG03aiPD8Vn-AnR7gL60MbPJAfzsO6R8,2157
281
281
  meta_lists/admin_site.py,sha256=M4uorELumZDIKD8SHs-AEX1doQFqXhRy-eCcRWYEu9k,165
282
282
  meta_lists/apps.py,sha256=aegHpyrHw188UxhNVFd-v35HP9wO7J7G9BYmliOOE0c,278
283
- meta_lists/list_data.py,sha256=kybIQAevrVKqncQHNoCatdgUpkLTV0S-Avim6hSgPWw,9819
283
+ meta_lists/list_data.py,sha256=jhj9KJ7VdOjoHxa56bxJ9cvg3eDjBldy0wbh_SySknc,9919
284
284
  meta_lists/models.py,sha256=3amfYtGe4GGtSpLXs36On8k_ZmpDzNs5ga54O-SIABs,3032
285
285
  meta_lists/urls.py,sha256=9NCrRvdkPXzH3L7VMCa0iQnz-j5tujzhvvtRRAGunV8,204
286
286
  meta_lists/migrations/0001_initial.py,sha256=87crhJGEUzUxe9TaNTzzKM6AjE3Pjw032PkhYrnRz9k,13881
@@ -301,6 +301,7 @@ meta_lists/migrations/0015_abnormalfootappearanceobservations_extra_value_and_mo
301
301
  meta_lists/migrations/0016_alter_abnormalfootappearanceobservations_options_and_more.py,sha256=FiXjIoQk0Q9LVRxmyBUA9k7ZAN3noUbvLdmqHhgBygo,20692
302
302
  meta_lists/migrations/0017_complications_dmmedications_dmtreatments_and_more.py,sha256=_Hq5WK2KgXy1OTFdE6ESH_txPi5YbduS0kl84GyU-YI,13041
303
303
  meta_lists/migrations/0018_missedreferralreasons.py,sha256=E_-Jrkwz_nAc3SND6EPdkWKeobi6q308J--mDM8JgHA,2639
304
+ meta_lists/migrations/0019_auto_20250128_0143.py,sha256=NtS06qHmBQnoGZhZTR-OAfmoyllmMAyyTozXGl1JdbM,1577
304
305
  meta_lists/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
305
306
  meta_lists/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
306
307
  meta_lists/tests/test_lists.py,sha256=qcp2emRyd5-cP2oLluy8MpUucBDQ8_GdUxjh2KbZPv4,212
@@ -753,7 +754,7 @@ meta_stats/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
753
754
  meta_stats/tests/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
754
755
  meta_stats/tests/tests/test_incidence.py,sha256=Uxv05_xZ0hZKtTBDow3goRcQrK5644j9NQwyW9d_CX8,313
755
756
  meta_subject/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
756
- meta_subject/action_items.py,sha256=Y0V_L6V8foKYEcZ8FxGLDfdiPoJNql47enKFRpClGeg,6642
757
+ meta_subject/action_items.py,sha256=eRONfgYX0DbSCI5JqFbMojiy86jDRvQgV-BUlQpmNog,6895
757
758
  meta_subject/admin_site.py,sha256=fxUn5QKgo6wYUG18HW11kVrPqWvmWV2_PzKbgZQM4pU,169
758
759
  meta_subject/apps.py,sha256=iAQ8lizUpKa4gJnCGkTsuRQPtGWmSjnshZn8rZUguO8,289
759
760
  meta_subject/baker_recipes.py,sha256=C8ag5z5MRczzb3MkYGL37DccQg1FykiLgxepBlitlh0,2741
@@ -761,7 +762,7 @@ meta_subject/choices.py,sha256=LjKRsEG0uGJow2BHshV_oKXdNYktNGn1Xj9H8SbGtBA,6782
761
762
  meta_subject/constants.py,sha256=6rpHsHj3CPV7ntdWxYScRhPVoj4YIxX2lUZdZ9lrFN0,704
762
763
  meta_subject/identifiers.py,sha256=pBYvMFXK7N2oNDMJJM2xLCvk0NuzLzzm15VqQ2Cp7Og,325
763
764
  meta_subject/urls.py,sha256=v2fM0R9gvt8MWdZj9cRnYU8xvqecLK5b_8leYVEtYZI,206
764
- meta_subject/admin/__init__.py,sha256=yMvCb_HcfG-7ZEee2R_HJJxKTobbpw1UTrneIwtbSuk,1734
765
+ meta_subject/admin/__init__.py,sha256=i95-mnCq78eCpSwsSPxtBLrdv665ivs3pJHjLeoc7g8,1791
765
766
  meta_subject/admin/autocomplete_admin.py,sha256=bVxma7KTHhKHWqLPxbP2GwiGcHeBUyMutTDXZ2RomEY,1158
766
767
  meta_subject/admin/birth_outcome_admin.py,sha256=TFqO3aeAWeMtgrgFrxE6zIBQaZ_b_1YC3msubO4vDc4,3233
767
768
  meta_subject/admin/complications_admin.py,sha256=qxaJVWW86Hg56T8IYfyM9SiP5IcPFNuMfIWBI9fqz90,1017
@@ -782,6 +783,7 @@ meta_subject/admin/malaria_test_admin.py,sha256=qLa5StnwN_2ytNYykXcLKwSJn6tc7e0-
782
783
  meta_subject/admin/medication_adherence_admin.py,sha256=mhKGcDHUParW6BATj9S2wa5Th3u_ndQRKVNnjYcxKyM,543
783
784
  meta_subject/admin/mnsi_admin.py,sha256=nF2tBC3pKA1eQ6EPdyX92ZoEOmW1B1mZRi5IDpF8cPk,1430
784
785
  meta_subject/admin/modeladmin.py,sha256=ehH9gMgTFBzmEzQj7sZboQgHdGQ3eaEgHjh0HmcDOVo,510
786
+ meta_subject/admin/next_appointment_admin.py,sha256=jludu5ag_ojc1GqjasvZW-x9uVDSmmk8ZDZR6E4IZUc,606
785
787
  meta_subject/admin/other_arv_regimens_admin.py,sha256=GsaKPaR6Chwuwk0DE-qpyq4xhiD0v979U2C4--gtG1k,1674
786
788
  meta_subject/admin/patient_history_admin.py,sha256=kXglsPOngnjYY2FQYP_YHoH5IcSJutGF14CBsSViplQ,1763
787
789
  meta_subject/admin/physical_exam_admin.py,sha256=nCcY42CQXbZCro4vsQUfw5gQ1KKs-zjsHPqP-KtUQQc,1858
@@ -815,7 +817,7 @@ meta_subject/form_validators/egfr_drop_notification_form_validator.py,sha256=y5M
815
817
  meta_subject/form_validators/followup_examination_form_validator.py,sha256=NS3Sa-bwC_HEe-CmezkFrbbjPanLe9p1v5ZOFspqgxg,4241
816
818
  meta_subject/form_validators/glucose_form_validator.py,sha256=ebtWmJo_0z8mlZzH377q4aTa9kY2R3CfCT5WtRxARb8,3371
817
819
  meta_subject/form_validators/health_economics_form_validator.py,sha256=kp-LQU4ydBXlnYFt-0xKuVSb8Y4irlhz9d_X8ppvWgE,250
818
- meta_subject/forms/__init__.py,sha256=1uQ6CIF9MA8KfrM0u_a_Z_eOC1JjGlF3k7MEkqD3XCI,1700
820
+ meta_subject/forms/__init__.py,sha256=LrGBLJ3Se3McgUOdcrDyTM4B7G8ChVCrxDq4DXiYDLE,1755
819
821
  meta_subject/forms/birth_outcomes_form.py,sha256=qqhZNQKiYk8C8CFebZTQB0hOm4ONrgkTG7hfuK7kW-o,374
820
822
  meta_subject/forms/complications_glycemia_form.py,sha256=yTm3qRDJ1wPuukmpf0s0lg-oXi8fZ5Y7D7T9V-CsOXk,375
821
823
  meta_subject/forms/concomitant_medication_form.py,sha256=eznM4YOSV0eSsc-qaQgkga76T76Oz6i8svyBaleW-gQ,375
@@ -831,6 +833,7 @@ meta_subject/forms/malaria_test_form.py,sha256=xQeF-wBq06anAU9it0lLvQhIxJoWoFc_b
831
833
  meta_subject/forms/medication_adherence_form.py,sha256=yjDmr3uIDwQXnph6mkCgluYEJgFCpXzUPoTVbivba0Y,865
832
834
  meta_subject/forms/mixins.py,sha256=MdiCuVB5pyD0ExZs48t0NiL_BiQD8pVwMoWbjHR3WBA,2084
833
835
  meta_subject/forms/mnsi_form.py,sha256=RLZqJlcZKvHyfoYoYSkz_HhdkLanYxY7CkVJH1Nu3ZA,323
836
+ meta_subject/forms/next_appointment_form.py,sha256=saEpcIPkwQ-QOCM4Sch8tt9t5RIQjZNJ3uBkcQovX8s,1080
834
837
  meta_subject/forms/other_arv_regimens_detail_form.py,sha256=dxFJBqAkKKfIAJ_HGbuUANbnbUxk-6Rf6c7c0GrkpjE,962
835
838
  meta_subject/forms/other_arv_regimens_form.py,sha256=TApyN2QYIlSYc3esVXjMdLhYE8JM7quRLqALf8Cnhu4,1687
836
839
  meta_subject/forms/patient_history_form.py,sha256=wVXMp5k21jWHKsm-FXvjBEN32PaF8Sw3r3KQzyVLl-k,1807
@@ -863,8 +866,8 @@ meta_subject/management/commands/create_missing_refills.py,sha256=IkxEOV2AHl2FYh
863
866
  meta_subject/management/commands/create_missing_rx.py,sha256=jAqgz9yxhaEL1XBN9FqM-5cPv1TpNtL4XdltLPArOEA,1463
864
867
  meta_subject/management/commands/missed.py,sha256=qTHggBxlJWcEF_V4cGtxe93UJXlaW-ON6m1SOpJzmgg,8209
865
868
  meta_subject/metadata_rules/__init__.py,sha256=U8fKGiHsbSWW27dWbTp2A2pCmdcFgybbJDhazP591cE,53
866
- meta_subject/metadata_rules/metadata_rules.py,sha256=Pe7YK1Ss9P_0vi75ImqC0eaOi3rgEGYeukanVzyXXAY,3981
867
- meta_subject/metadata_rules/predicates.py,sha256=QAaguLepmT9DQnF3TdXvdLZk0dBF7skGsZw1KnjG31g,9214
869
+ meta_subject/metadata_rules/metadata_rules.py,sha256=CeZKXkr_sFsMlZK3CoU8buF51hqSH5hyxTWS92ZfBGk,4323
870
+ meta_subject/metadata_rules/predicates.py,sha256=Neu5O34ly2J2H5GrC5oot1v5ZwU1uaPQFbTerzPssbQ,10015
868
871
  meta_subject/migrations/0001_initial.py,sha256=UHMfeHsfaGWg97-gMxfcmD4_-xDnrj-cslhT_mZQdZw,408932
869
872
  meta_subject/migrations/0002_auto_20191021_0353.py,sha256=ekA3FFPdsAGmqWt2wrwQahzuwTE98e1VZLouXbZocrY,29351
870
873
  meta_subject/migrations/0003_auto_20191021_0534.py,sha256=Ye9au73hXxbvd1tBmrafin20NPWUZfhxj50x4S-tYqk,4024
@@ -1080,6 +1083,11 @@ meta_subject/migrations/0212_auto_20240827_2222.py,sha256=ClHxTDTE9Ft6w8qT2LMSfD
1080
1083
  meta_subject/migrations/0213_rename_bloodresultslipid_bloodresultslipids_and_more.py,sha256=51UvT_rl0R2phHX0-QCdJqIPbfDcWzVMWdONwhWQ7Ws,1129
1081
1084
  meta_subject/migrations/0214_historicalstudymedication_stock_codes_and_more.py,sha256=Mzz4aPKvLeANXy9osTlefXXqbi-VwTA1SOBewkTLZ1I,1422
1082
1085
  meta_subject/migrations/0215_alter_historicalstudymedication_stock_codes_and_more.py,sha256=bUPpZPSwmRGnXOdd6kw1fmkGPEHdA0SWQ_P6wMtKyvI,1580
1086
+ meta_subject/migrations/0216_historicalnextappointment_nextappointment.py,sha256=u8HHxBb8Wa6qv71G5H6L8kCd8-BaeoWhGIxUjuc_qkU,22670
1087
+ meta_subject/migrations/0217_alter_historicalnextappointment_appt_datetime_and_more.py,sha256=4nRX3nS81TBEUtqQSke3YrH_i7GePwoHE3QmBByoBr0,1442
1088
+ meta_subject/migrations/0218_alter_historicalnextappointment_appt_date_and_more.py,sha256=4YpEw1btk2G3wjx2SJKqTOEWymCTbd8iD640Ttpf-cs,1848
1089
+ meta_subject/migrations/0219_remove_historicalnextappointment_allow_create_interim_and_more.py,sha256=UCSUXzoa-TSqv7pPfZpg5jI1siKDFBXRknH6OFv0tL4,3476
1090
+ meta_subject/migrations/0220_historicalbloodresultsgludummy_bloodresultsgludummy.py,sha256=6TT5p5hQAhkL-vc3mo7xAAoZlQSoPAQ_KBTWNxYkr-0,34009
1083
1091
  meta_subject/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1084
1092
  meta_subject/model_mixins/__init__.py,sha256=6DdDDOwDdagrz6Q7X9lxuAVszsFWFhwPqLz4JOD85Wo,286
1085
1093
  meta_subject/model_mixins/arv_history_model_mixin.py,sha256=6ILacF2koyYmwZIFHmmQO1uIT1eWzrahXxhAlxpQiX0,2898
@@ -1087,7 +1095,7 @@ meta_subject/model_mixins/crf_model_mixin.py,sha256=UK1ycbYwaZ8LSNTJm74QJ5c-01HD
1087
1095
  meta_subject/model_mixins/crf_with_action_model_mixin.py,sha256=q1Q16YyPjQlpDtCPOXRkO5C7Vr7JO_QL8xWC48Uz33M,298
1088
1096
  meta_subject/model_mixins/search_slug_model_mixin.py,sha256=r5KmTykU0qV4JymMMKP2IBwAP8Z5hDnVJix-rO2PvME,296
1089
1097
  meta_subject/model_mixins/vitals_fields_model_mixin.py,sha256=JYh0w1eEFLR_BCvzHb2ldwNIkyINbfvef-SL4_wA-NY,1160
1090
- meta_subject/models/__init__.py,sha256=lsN0x_SG3N4J8-2tdxa9EerdUH3CqZIv68QtLKIIplg,1763
1098
+ meta_subject/models/__init__.py,sha256=c8EYwYsi7e3dAqhsw_KeF6MRyBQStC_rSpthVpO_a98,1835
1091
1099
  meta_subject/models/birth_outcomes.py,sha256=zikxatYZvL1qvnJ6JtVZ5aw8LCKLwQNXi6cP5F-5Jj0,3124
1092
1100
  meta_subject/models/complications.py,sha256=lkUoM3wJ9GuCFkuBUVxbCRSWfl3UtiVNSoMmkPKQdzg,1849
1093
1101
  meta_subject/models/complications_glycemia.py,sha256=2wHind-dDsPY5J4M0pUbRzjp72Brz990oDzCbF-V1CM,6056
@@ -1105,6 +1113,7 @@ meta_subject/models/hepatitis_test.py,sha256=zhUhRDAD_rMu_8kyiA4LFYG7YEHTK2c8Tpq
1105
1113
  meta_subject/models/malaria_test.py,sha256=4gQNBnvLDv70rjRcFBOpLPmYL8eeuqs0lRsJ7LrFqHM,343
1106
1114
  meta_subject/models/medication_adherence.py,sha256=7a9WQAvgin2WeSgznNDNdet69JTT7DO61hfMseF4cVY,399
1107
1115
  meta_subject/models/mnsi.py,sha256=tD6Sh4aQ1Oszt3SLzhgOLwxXr8zW8jvEEETEJP75Hdc,284
1116
+ meta_subject/models/next_appointment.py,sha256=mQBdki1XR0s3XfLw8X6X8w1-aCZuY0uV25Uwvx1QjcU,530
1108
1117
  meta_subject/models/off_study_drug.py,sha256=puKUqsSsw48BxzfOCT2DS44Kal3SUFlguAk2q6MS8OY,706
1109
1118
  meta_subject/models/other_arv_regimens.py,sha256=AYiMgJVcpcw3Vn-I7ePl-zOEMlkKgWHtWwWmsDjsjyw,607
1110
1119
  meta_subject/models/other_arv_regimens_detail.py,sha256=UxbTAHIuTCjAZzQlZp1x5HVbv8Oa3-oIHnoRsFNXds8,1828
@@ -1120,8 +1129,9 @@ meta_subject/models/subject_visit_missed.py,sha256=_qXuKzhFukRm5k44GgdT368MuOmOZ
1120
1129
  meta_subject/models/todo.txt,sha256=yMP-BRI7dB6iwU0FicB3A0muydm6qlqGTSyy7Bvh2f4,248
1121
1130
  meta_subject/models/urine_dipstick_test.py,sha256=T_IrBRAJ_6ckJUjT_MHKaOzfNkxk5zso0JCsroLM8jc,1178
1122
1131
  meta_subject/models/urine_pregnancy.py,sha256=LVC4PonyoSbnMJJN0EVIZo7iCuBzm6-W6ne7YxHUBEY,1336
1123
- meta_subject/models/blood_results/__init__.py,sha256=j6_4aR0eA58TaErYyh_vFyIKaXVcGw5o97Foa7Ib2JE,292
1132
+ meta_subject/models/blood_results/__init__.py,sha256=ktxJOUM5PO3mXpLHxiSjt7Tmi5JACUbeCWjXhUK6qyU,344
1124
1133
  meta_subject/models/blood_results/blood_results_fbc.py,sha256=kkOqCsqeIvCf2rw7vHGWMCEgo1_yiMDtTOi44aKtBro,1324
1134
+ meta_subject/models/blood_results/blood_results_glu.py,sha256=QvIZjXWQ4qLfbGz5TbTIPHMJh2dtmi2kXTjVXP9xqYg,1029
1125
1135
  meta_subject/models/blood_results/blood_results_hba1c.py,sha256=KaPJhpRPmR_-9oRQ7cdiVPle9exGPZDxjMc6WeyS1mQ,1036
1126
1136
  meta_subject/models/blood_results/blood_results_ins.py,sha256=uHHFdry5s70UGTxllAlN4hhF4rcC2ybc6mCV_Rd1lCY,1052
1127
1137
  meta_subject/models/blood_results/blood_results_lft.py,sha256=VRWKM5292AuHd-BZDC9RHA9sb_xdPwlj2OIKeQAzpRE,1235
@@ -1149,6 +1159,7 @@ meta_subject/tests/tests/test_manager_order.py,sha256=wmVxMd85mJ6HGAL_3Z_mSp_mqe
1149
1159
  meta_subject/tests/tests/test_medication_adherence.py,sha256=y_JDajAqKuQTGDxeQwq4O4xwKj6azCfUnDFaW5SjJIM,2611
1150
1160
  meta_subject/tests/tests/test_metadata_rules.py,sha256=4mSQVXf4EteDUUjrRkpKhOzDukEBC1M9IXkyg0MEAOA,5712
1151
1161
  meta_subject/tests/tests/test_mnsi.py,sha256=MidXvGYmzw7gtZHk33dfMrNdS6iN1JFnfmAyindKsIo,14706
1162
+ meta_subject/tests/tests/test_next_appointment.py,sha256=OVe6Jf6uaR5ch28skkNrr4h5uMTnvOpPSvEJjWnsoKo,9938
1152
1163
  meta_subject/tests/tests/test_patient_history_form.py,sha256=JzqCx_-g2jeknngGl94FhZNVCl0CfnWIAZ9R11y7-wY,2827
1153
1164
  meta_subject/tests/tests/test_physical_exam.py,sha256=U3TKOPWTVu8iXxsS8LGgJJEY8e2sKJ5iTBcIWIHKCAo,2947
1154
1165
  meta_subject/tests/tests/test_sf12.py,sha256=5Daf-R4EeLjfDpsC5PZELfPIqY--joGzrj8nPVUiatI,6837
@@ -1164,12 +1175,12 @@ meta_visit_schedule/tests/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
1164
1175
  meta_visit_schedule/tests/tests/test_schedule.py,sha256=858fXo-PvbppgIsCAGll05fqnuWW6f-vMIwnvRLZgnc,7351
1165
1176
  meta_visit_schedule/visit_schedules/__init__.py,sha256=j0Q8tAGhHHbFBd3R-iLRy4QB47WgtucWG7xCLLfVvFU,339
1166
1177
  meta_visit_schedule/visit_schedules/phase_three/__init__.py,sha256=18ken4S10X0dkEFHj1EFO2M4xblXD04cjfhzIEkhYUQ,74
1167
- meta_visit_schedule/visit_schedules/phase_three/crfs.py,sha256=mPfCfbwvTyWNBwZWX3_sOw6-GAAYhIydZvIElWYjhVk,16060
1178
+ meta_visit_schedule/visit_schedules/phase_three/crfs.py,sha256=JcAHxtui3ZEnr7wjih34V8yuTUJ6ZVWTDFANabYYovo,17563
1168
1179
  meta_visit_schedule/visit_schedules/phase_three/crfs_pregnancy.py,sha256=_I6IVLMC3-KlpI86eii790mlx-p2vxWxvNRKD927rXo,169
1169
1180
  meta_visit_schedule/visit_schedules/phase_three/requisitions.py,sha256=Noeki8zX2MCwQVmCCWfuOyh_aN4YC-cyhUmrAZP8d5g,4579
1170
1181
  meta_visit_schedule/visit_schedules/phase_three/schedule.py,sha256=5vT_J_IUap-ohYigIt327noAAGXt77yDOact4rJuxEQ,8231
1171
1182
  meta_visit_schedule/visit_schedules/phase_three/schedule_dm_referral.py,sha256=Txnmf03jPyFhC2gOseywHyyaGJmJFKAET-x12hknW-I,1752
1172
- meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py,sha256=0V2t68Moyla6MfmAyOU8c_bzN45ksADc-jDf8ZOB6Pw,1123
1183
+ meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py,sha256=m5KLFK6sPmUwKBYKD1OVZHNZQDiG9M1-VeBXvN1AGF0,1123
1173
1184
  meta_visit_schedule/visit_schedules/phase_three/visit_schedule.py,sha256=ak4qazeKlpIlvpqrK9hDDO0fwWuWyvb4Ec-JU31IJxc,654
1174
1185
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1175
1186
  tests/holidays.csv,sha256=Ywr5pK_caGUJMgRwLzjMeSEUuyEpUWyJE5aJkfbg3bg,539
@@ -1184,9 +1195,9 @@ tests/etc/user-rsa-restricted-private.pem,sha256=CUcHW9bznWdmmASN00hCzvxFPAFl4N2
1184
1195
  tests/etc/user-rsa-restricted-public.pem,sha256=mt84djoL-uHw6Wc5SJh0zml6VzXulnf8eQSFg7-fheg,450
1185
1196
  tests/etc/user-salt-local.key,sha256=x5anBw9fvbHurczouT3CjrkWb_xs7Ypm1htIJsgiuiw,256
1186
1197
  tests/etc/user-salt-restricted.key,sha256=pxmpcfBRNB-4C6wTvHXz-9fOfJgKIFOjaAF8ZFfa4q4,256
1187
- meta_edc-1.0.3.dist-info/AUTHORS,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1188
- meta_edc-1.0.3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1189
- meta_edc-1.0.3.dist-info/METADATA,sha256=oR_0N4H1Hizx_OekvtjQH--oacuwLIOD5Ge5w8s6wqQ,43527
1190
- meta_edc-1.0.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
1191
- meta_edc-1.0.3.dist-info/top_level.txt,sha256=RkzjNXwRq2kg_uZ_1bDwPUntijSXoY2YBqtByDwvvrc,244
1192
- meta_edc-1.0.3.dist-info/RECORD,,
1198
+ meta_edc-1.0.4.dist-info/AUTHORS,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1199
+ meta_edc-1.0.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1200
+ meta_edc-1.0.4.dist-info/METADATA,sha256=orwfOWZimxYfYXbqfvPe6ihe-UWsUPsfkbFcik5CxaY,43529
1201
+ meta_edc-1.0.4.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
1202
+ meta_edc-1.0.4.dist-info/top_level.txt,sha256=RkzjNXwRq2kg_uZ_1bDwPUntijSXoY2YBqtByDwvvrc,244
1203
+ meta_edc-1.0.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
meta_lists/list_data.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from edc_constants.constants import (
2
+ CLINIC,
2
3
  DEAD,
3
4
  DELIVERY,
4
5
  DIABETES,
@@ -236,4 +237,7 @@ list_data = {
236
237
  ("stigma", "Concerned about stigma"),
237
238
  (OTHER, "Other reason (specify below)"),
238
239
  ],
240
+ "edc_facility.healthfacilitytypes": [
241
+ (CLINIC, "META Study Clinic"),
242
+ ],
239
243
  }
@@ -0,0 +1,48 @@
1
+ # Generated by Django 6.0 on 2025-01-27 22:43
2
+ from django.apps import apps as django_apps
3
+ from django.core.exceptions import ObjectDoesNotExist
4
+ from django.db import migrations
5
+ from edc_facility.utils import get_health_facility_model_cls
6
+ from edc_sites.site import sites as site_sites
7
+ from edc_sites.utils import get_site_model_cls
8
+
9
+ from meta_lists.list_data import list_data
10
+
11
+
12
+ def update_healthfacility(apps, schema_editor):
13
+ health_facility_model_cls = get_health_facility_model_cls()
14
+
15
+ name, display_name = list_data.get("edc_facility.healthfacilitytypes")[0]
16
+ try:
17
+ health_facility_type = django_apps.get_model(
18
+ "edc_facility.healthfacilitytypes"
19
+ ).objects.get(name=name)
20
+ except ObjectDoesNotExist:
21
+ health_facility_type = django_apps.get_model(
22
+ "edc_facility.healthfacilitytypes"
23
+ ).objects.create(name=name, display_name=display_name)
24
+
25
+ for site_obj in get_site_model_cls().objects.all():
26
+ single_site = site_sites.get(site_obj.id)
27
+ health_facility_model_cls.objects.create(
28
+ name=single_site.name,
29
+ title=single_site.title,
30
+ mon=True,
31
+ tue=True,
32
+ wed=True,
33
+ thu=True,
34
+ fri=True,
35
+ sat=False,
36
+ sun=False,
37
+ site_id=site_obj.id,
38
+ health_facility_type=health_facility_type,
39
+ )
40
+
41
+
42
+ class Migration(migrations.Migration):
43
+
44
+ dependencies = [
45
+ ("meta_lists", "0018_missedreferralreasons"),
46
+ ]
47
+
48
+ operations = [migrations.RunPython(update_healthfacility)]
@@ -4,8 +4,11 @@ from edc_action_item.site_action_items import AlreadyRegistered
4
4
  from edc_adverse_event.constants import AE_INITIAL_ACTION
5
5
  from edc_constants.constants import HIGH_PRIORITY, NEW, NONE, POS, YES
6
6
  from edc_egfr.constants import EGFR_DROP_NOTIFICATION_ACTION
7
+ from edc_lab_results.action_items import BloodResultsFbcAction
8
+ from edc_lab_results.action_items import (
9
+ BloodResultsGluAction as BaseBloodResultsGluAction,
10
+ )
7
11
  from edc_lab_results.action_items import (
8
- BloodResultsFbcAction,
9
12
  BloodResultsHba1cAction,
10
13
  BloodResultsLftAction,
11
14
  BloodResultsLipidsAction,
@@ -122,6 +125,10 @@ class BloodResultsRftAction(BaseBloodResultsRftAction):
122
125
  return next_actions
123
126
 
124
127
 
128
+ class BloodResultsGluAction(BaseBloodResultsGluAction):
129
+ reference_model = "meta_subject.bloodresultsgludummy"
130
+
131
+
125
132
  class DeliveryAction(ActionWithNotification):
126
133
  name = DELIVERY_ACTION
127
134
  display_name = "Submit Delivery Form"
@@ -22,6 +22,7 @@ from .hepatitis_test_admin import HepatitisTestAdmin
22
22
  from .malaria_test_admin import MalariaTestAdmin
23
23
  from .medication_adherence_admin import MedicationAdherenceAdmin
24
24
  from .mnsi_admin import MnsiAdmin
25
+ from .next_appointment_admin import NextAppointmentAdmin
25
26
  from .other_arv_regimens_admin import OtherArvRegimensAdmin
26
27
  from .patient_history_admin import PatientHistoryAdmin
27
28
  from .physical_exam_admin import PhysicalExamAdmin
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ from django.contrib import admin
4
+ from edc_appointment.modeladmin_mixins import NextAppointmentCrfModelAdminMixin
5
+ from edc_model_admin.history import SimpleHistoryAdmin
6
+
7
+ from ..admin_site import meta_subject_admin
8
+ from ..forms import NextAppointmentForm
9
+ from ..models import NextAppointment
10
+ from .modeladmin import CrfModelAdminMixin
11
+
12
+ __all__ = ["NextAppointmentAdmin"]
13
+
14
+
15
+ @admin.register(NextAppointment, site=meta_subject_admin)
16
+ class NextAppointmentAdmin(
17
+ CrfModelAdminMixin, NextAppointmentCrfModelAdminMixin, SimpleHistoryAdmin
18
+ ):
19
+
20
+ form = NextAppointmentForm
@@ -22,6 +22,7 @@ from .hepatitis_test_form import HepatitisTestForm
22
22
  from .malaria_test_form import MalariaTestForm
23
23
  from .medication_adherence_form import MedicationAdherenceForm
24
24
  from .mnsi_form import MnsiForm
25
+ from .next_appointment_form import NextAppointmentForm
25
26
  from .other_arv_regimens_detail_form import OtherArvRegimensDetailForm
26
27
  from .other_arv_regimens_form import OtherArvRegimensForm
27
28
  from .patient_history_form import PatientHistoryForm
@@ -0,0 +1,37 @@
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
+
22
+ form_validator_cls = NextAppointmentCrfFormValidator
23
+
24
+ class Meta:
25
+ model = NextAppointment
26
+ fields = "__all__"
27
+ labels = {
28
+ "appt_date": "Next scheduled appointment date",
29
+ "visitschedule": "Next scheduled appointment",
30
+ }
31
+ help_texts = {
32
+ "appt_date": (
33
+ "Default recommended. If changed, should be within "
34
+ "the window period of the next appointment"
35
+ ),
36
+ "visitschedule": "Default recommended. Can only be the next visit",
37
+ }
@@ -160,3 +160,17 @@ class Eq53dlRuleGroup(CrfRuleGroup):
160
160
  class Meta:
161
161
  app_label = "meta_subject"
162
162
  source_model = "meta_subject.subjectvisit"
163
+
164
+
165
+ @register()
166
+ class NextAppointmentRuleGroup(CrfRuleGroup):
167
+ next_appt = CrfRule(
168
+ predicate=pc.next_appt_required,
169
+ consequence=REQUIRED,
170
+ alternative=NOT_REQUIRED,
171
+ target_models=["nextappointment"],
172
+ )
173
+
174
+ class Meta:
175
+ app_label = "meta_subject"
176
+ source_model = "meta_subject.subjectvisit"
@@ -3,6 +3,7 @@ from zoneinfo import ZoneInfo
3
3
 
4
4
  from django.apps import apps as django_apps
5
5
  from django.core.exceptions import ObjectDoesNotExist
6
+ from edc_appointment.constants import NEW_APPT
6
7
  from edc_constants.constants import YES
7
8
  from edc_lab_panel.panels import hba1c_panel, insulin_panel
8
9
  from edc_metadata.metadata_rules import PersistantSingletonMixin
@@ -69,6 +70,12 @@ def hba1c_requisition_required_at_baseline(visit):
69
70
  class Predicates(PersistantSingletonMixin):
70
71
  app_label = "meta_subject"
71
72
 
73
+ @staticmethod
74
+ def next_appt_required(visit, **kwargs):
75
+ if visit.appointment.next and visit.appointment.next.appt_status == NEW_APPT:
76
+ return True
77
+ return False
78
+
72
79
  @staticmethod
73
80
  def glucose_required(visit, **kwargs):
74
81
  if visit.visit_code in [MONTH12, MONTH24, MONTH36, MONTH48]:
@@ -213,7 +220,10 @@ class Predicates(PersistantSingletonMixin):
213
220
  """
214
221
  model_cls = django_apps.get_model(f"{self.app_label}.mnsi")
215
222
  required = True
216
- if visit.visit_code_sequence != 0:
223
+
224
+ if self.offschedule_today(visit):
225
+ return True
226
+ elif visit.visit_code_sequence != 0:
217
227
  required = False
218
228
  elif visit.visit_code not in [
219
229
  MONTH1,
@@ -250,7 +260,9 @@ class Predicates(PersistantSingletonMixin):
250
260
 
251
261
  def sf12_required(self, visit, **kwargs):
252
262
  model = f"{self.app_label}.sf12"
253
- if visit.visit_code_sequence == 0 and visit.visit_code in [MONTH36, MONTH48]:
263
+ if self.offschedule_today(visit):
264
+ return True
265
+ elif visit.visit_code_sequence == 0 and visit.visit_code in [MONTH36, MONTH48]:
254
266
  return True
255
267
  return self.persistant_singleton_required(
256
268
  visit, model=model, exclude_visit_codes=[DAY1]
@@ -258,8 +270,22 @@ class Predicates(PersistantSingletonMixin):
258
270
 
259
271
  def eq5d3l_required(self, visit, **kwargs):
260
272
  model = f"{self.app_label}.eq5d3l"
261
- if visit.visit_code_sequence == 0 and visit.visit_code in [MONTH36, MONTH48]:
273
+ if self.offschedule_today(visit):
274
+ return True
275
+ elif visit.visit_code_sequence == 0 and visit.visit_code in [MONTH36, MONTH48]:
262
276
  return True
263
277
  return self.persistant_singleton_required(
264
278
  visit, model=model, exclude_visit_codes=[DAY1]
265
279
  )
280
+
281
+ def offschedule_today(self, visit):
282
+ try:
283
+ obj = django_apps.get_model(f"{self.app_label}.nextappointment").objects.get(
284
+ subject_visit=visit
285
+ )
286
+ except ObjectDoesNotExist:
287
+ pass
288
+ else:
289
+ if obj.offschedule_today == YES:
290
+ return True
291
+ return False