meta-edc 0.3.7__py3-none-any.whl → 0.3.15__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- meta_auth/auth_objects.py +10 -3
- meta_consent/baker_recipes.py +4 -4
- meta_consent/consents.py +1 -1
- meta_consent/migrations/0025_alter_historicalsubjectconsent_first_name_and_more.py +151 -0
- meta_consent/models/signals.py +16 -13
- meta_consent/models/subject_consent_v1.py +1 -3
- meta_consent/tests/tests/test_form_validators.py +1 -1
- meta_dashboard/templates/meta_dashboard/bootstrap3/screening/listboard.html +4 -4
- meta_dashboard/templates/meta_dashboard/bootstrap3/subject/listboard.html +1 -2
- meta_edc/settings/debug.py +9 -9
- meta_edc/settings/defaults.py +25 -18
- meta_edc/settings/live.py +1 -9
- meta_edc/settings/uat.py +1 -14
- meta_edc/templates/meta_edc/bootstrap3/home.html +8 -5
- meta_edc/tests/test_settings.py +176 -0
- meta_edc/tests/tests/test_endpoints.py +20 -19
- meta_edc/urls.py +1 -1
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/METADATA +5 -4
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/RECORD +128 -74
- meta_prn/action_items.py +44 -2
- meta_prn/admin/__init__.py +3 -0
- meta_prn/admin/dm_referral_admin.py +49 -0
- meta_prn/admin/offschedule_dm_referral_admin.py +47 -0
- meta_prn/admin/onschedule_dm_referral_admin.py +39 -0
- meta_prn/baker_recipes.py +8 -1
- meta_prn/choices.py +2 -1
- meta_prn/constants.py +4 -1
- meta_prn/forms/__init__.py +2 -0
- meta_prn/forms/dm_referral_form.py +40 -0
- meta_prn/forms/offschedule_dm_referral_form.py +35 -0
- meta_prn/forms/offschedule_form.py +6 -0
- meta_prn/migrations/0057_historicalonscheduledmreferral_and_more.py +1156 -0
- meta_prn/migrations/0058_dmreferral_referral_note_and_more.py +29 -0
- meta_prn/migrations/0059_alter_historicaloffstudymedication_reason_and_more.py +53 -0
- meta_prn/models/__init__.py +13 -2
- meta_prn/models/dm_referral.py +39 -0
- meta_prn/models/offschedule.py +15 -1
- meta_prn/models/onschedule.py +6 -0
- meta_prn/models/signals.py +41 -1
- meta_prn/tests/tests/test_dm_referral.py +206 -0
- meta_screening/form_validators/screening_part_two.py +1 -1
- meta_screening/migrations/0062_remove_icpreferral_site_and_more.py +27 -0
- meta_screening/migrations/0063_alter_historicalscreeningpartone_fasting_duration_str_and_more.py +184 -0
- meta_screening/migrations/0064_remove_historicalscreeningpartone_fasting_duration_minutes_and_more.py +126 -0
- meta_screening/migrations/0065_auto_20240516_0352.py +31 -0
- meta_screening/migrations/0066_alter_historicalscreeningpartone_fasting_duration_delta_and_more.py +103 -0
- meta_screening/models/__init__.py +1 -1
- meta_screening/tests/meta_test_case_mixin.py +2 -2
- meta_screening/tests/options.py +3 -3
- meta_sites/__init__.py +0 -1
- meta_sites/sites.py +8 -7
- meta_subject/action_items.py +23 -0
- meta_subject/admin/__init__.py +1 -1
- meta_subject/admin/birth_outcome_admin.py +2 -3
- meta_subject/admin/delivery_admin.py +0 -1
- meta_subject/admin/diabetes/__init__.py +2 -0
- meta_subject/admin/diabetes/dm_diagnosis_admin.py +89 -0
- meta_subject/admin/{dm_referral_followup_admin.py → diabetes/dm_followup_admin.py} +15 -8
- meta_subject/admin/glucose_admin.py +1 -1
- meta_subject/admin/glucose_fbg_admin.py +34 -8
- meta_subject/admin/subject_visit_admin.py +4 -1
- meta_subject/baker_recipes.py +6 -0
- meta_subject/choices.py +8 -0
- meta_subject/constants.py +2 -1
- meta_subject/form_validators/__init__.py +2 -1
- meta_subject/form_validators/dm_diagnosis_form_validator.py +38 -0
- meta_subject/form_validators/dm_dx_result_form_validator.py +7 -0
- meta_subject/form_validators/{dm_referral_followup_form_validator.py → dm_followup_form_validator.py} +41 -2
- meta_subject/forms/__init__.py +1 -0
- meta_subject/forms/diabetes/__init__.py +3 -0
- meta_subject/forms/diabetes/dm_diagnosis_form.py +13 -0
- meta_subject/forms/diabetes/dm_dx_result_form.py +11 -0
- meta_subject/forms/diabetes/dm_followup_form.py +25 -0
- meta_subject/forms/glucose_fbg_form.py +38 -16
- meta_subject/forms/subject_visit_form.py +16 -0
- meta_subject/metadata_rules/metadata_rules.py +14 -0
- meta_subject/metadata_rules/predicates.py +22 -0
- meta_subject/migrations/0181_dmreferralfollowup_action_identifier_and_more.py +143 -0
- meta_subject/migrations/0182_rename_dmreferralfollowup_dmfollowup_and_more.py +54 -0
- meta_subject/migrations/0183_alter_dmfollowup_on_dm_medications_and_more.py +31 -0
- meta_subject/migrations/0184_alter_glucose_options_and_more.py +31 -0
- meta_subject/migrations/0185_alter_bloodresultsins_fasting_duration_str_and_more.py +82 -0
- meta_subject/migrations/0186_healtheconomicsupdate_singleton_field_and_more.py +55 -0
- meta_subject/migrations/0187_dmdiagnosis_historicaldmdiagnosis_dmdxresult_and_more.py +451 -0
- meta_subject/migrations/0188_historicaldmdxresult_dmdxresult.py +403 -0
- meta_subject/migrations/0189_alter_dmdxresult_options_and_more.py +116 -0
- meta_subject/migrations/0190_dmdiagnosis_dx_no_tmg_reason_and_more.py +65 -0
- meta_subject/migrations/0191_alter_dmdiagnosis_dx_no_tmg_reason_and_more.py +70 -0
- meta_subject/migrations/0192_rename_glucose_quantifier_glucosefbg_fbg_quantifier_and_more.py +44 -0
- meta_subject/migrations/0193_alter_glucosefbg_fbg_value_and_more.py +44 -0
- meta_subject/migrations/0194_remove_glucosefbg_assay_datetime_and_more.py +166 -0
- meta_subject/migrations/0195_alter_glucosefbg_fbg_datetime_and_more.py +27 -0
- meta_subject/migrations/0196_glucosefbg_fbg_not_performed_reason_and_more.py +49 -0
- meta_subject/migrations/0197_glucosefbg_fasting_duration_estimated_and_more.py +33 -0
- meta_subject/migrations/0198_alter_glucosefbg_fasting_duration_estimated_and_more.py +33 -0
- meta_subject/migrations/0199_auto_20240516_0247.py +18 -0
- meta_subject/migrations/0200_rename_fasting_duration_minutes_bloodresultsins_fasting_duration_delta_and_more.py +43 -0
- meta_subject/migrations/0201_alter_bloodresultsins_fasting_duration_delta_and_more.py +58 -0
- meta_subject/migrations/0202_auto_20240516_0315.py +32 -0
- meta_subject/migrations/0203_alter_bloodresultsins_fasting_duration_delta_and_more.py +67 -0
- meta_subject/migrations/0204_glucosefbg_repeat_fbg_date_and_more.py +27 -0
- meta_subject/migrations/0205_historicalsubjectrequisition_crf_status_and_more.py +80 -0
- meta_subject/migrations/0206_bloodresultsfbc_crf_status_and_more.py +62 -0
- meta_subject/models/__init__.py +1 -1
- meta_subject/models/blood_results/blood_results_fbc.py +3 -2
- meta_subject/models/blood_results/blood_results_hba1c.py +2 -0
- meta_subject/models/blood_results/blood_results_ins.py +2 -0
- meta_subject/models/blood_results/blood_results_lft.py +2 -0
- meta_subject/models/blood_results/blood_results_lipid.py +2 -0
- meta_subject/models/blood_results/blood_results_rft.py +2 -0
- meta_subject/models/diabetes/__init__.py +3 -0
- meta_subject/models/diabetes/dm_diagnosis.py +50 -0
- meta_subject/models/diabetes/dm_dx_result.py +70 -0
- meta_subject/models/{dm_referral_followup.py → diabetes/dm_followup.py} +18 -6
- meta_subject/models/glucose.py +5 -15
- meta_subject/models/glucose_fbg.py +40 -51
- meta_subject/models/health_economics/health_economics_update.py +2 -0
- meta_subject/models/subject_requisition.py +3 -4
- meta_subject/tests/tests/test_egfr.py +6 -5
- meta_subject/tests/tests/test_metadata_rules.py +32 -2
- meta_visit_schedule/constants.py +3 -1
- meta_visit_schedule/visit_schedules/phase_three/crfs.py +12 -1
- meta_visit_schedule/visit_schedules/phase_three/schedule_dm_referral.py +60 -0
- meta_visit_schedule/visit_schedules/phase_three/visit_schedule.py +2 -0
- meta_subject/forms/dm_referral_followup.py +0 -18
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/AUTHORS +0 -0
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/LICENSE +0 -0
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/WHEEL +0 -0
- {meta_edc-0.3.7.dist-info → meta_edc-0.3.15.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
# Generated by Django 4.2.11 on 2024-05-16 20:08
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
import edc_crf.model_mixins.crf_status_model_mixin
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
("meta_subject", "0204_glucosefbg_repeat_fbg_date_and_more"),
|
11
|
+
]
|
12
|
+
|
13
|
+
operations = [
|
14
|
+
migrations.AddField(
|
15
|
+
model_name="historicalsubjectrequisition",
|
16
|
+
name="crf_status",
|
17
|
+
field=models.CharField(
|
18
|
+
choices=[
|
19
|
+
("INCOMPLETE", "Incomplete (some data pending)"),
|
20
|
+
("COMPLETE", "Complete"),
|
21
|
+
],
|
22
|
+
default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
|
23
|
+
help_text="If some data is still pending, flag this CRF as incomplete",
|
24
|
+
max_length=25,
|
25
|
+
verbose_name="CRF status",
|
26
|
+
),
|
27
|
+
),
|
28
|
+
migrations.AddField(
|
29
|
+
model_name="historicalsubjectrequisition",
|
30
|
+
name="crf_status_comments",
|
31
|
+
field=models.TextField(
|
32
|
+
blank=True,
|
33
|
+
help_text="for example, why some data is still pending",
|
34
|
+
null=True,
|
35
|
+
verbose_name="Any comments related to status of this CRF",
|
36
|
+
),
|
37
|
+
),
|
38
|
+
migrations.AddField(
|
39
|
+
model_name="subjectrequisition",
|
40
|
+
name="crf_status",
|
41
|
+
field=models.CharField(
|
42
|
+
choices=[
|
43
|
+
("INCOMPLETE", "Incomplete (some data pending)"),
|
44
|
+
("COMPLETE", "Complete"),
|
45
|
+
],
|
46
|
+
default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
|
47
|
+
help_text="If some data is still pending, flag this CRF as incomplete",
|
48
|
+
max_length=25,
|
49
|
+
verbose_name="CRF status",
|
50
|
+
),
|
51
|
+
),
|
52
|
+
migrations.AddField(
|
53
|
+
model_name="subjectrequisition",
|
54
|
+
name="crf_status_comments",
|
55
|
+
field=models.TextField(
|
56
|
+
blank=True,
|
57
|
+
help_text="for example, why some data is still pending",
|
58
|
+
null=True,
|
59
|
+
verbose_name="Any comments related to status of this CRF",
|
60
|
+
),
|
61
|
+
),
|
62
|
+
migrations.AlterField(
|
63
|
+
model_name="dmdxresult",
|
64
|
+
name="utestid",
|
65
|
+
field=models.CharField(
|
66
|
+
choices=[("fbg", "FBG mmol/L"), ("ogtt", "OGTT mmol/L"), ("hba1c", "HbA1c %")],
|
67
|
+
max_length=15,
|
68
|
+
verbose_name="Test",
|
69
|
+
),
|
70
|
+
),
|
71
|
+
migrations.AlterField(
|
72
|
+
model_name="historicaldmdxresult",
|
73
|
+
name="utestid",
|
74
|
+
field=models.CharField(
|
75
|
+
choices=[("fbg", "FBG mmol/L"), ("ogtt", "OGTT mmol/L"), ("hba1c", "HbA1c %")],
|
76
|
+
max_length=15,
|
77
|
+
verbose_name="Test",
|
78
|
+
),
|
79
|
+
),
|
80
|
+
]
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by Django 4.2.11 on 2024-05-17 14:31
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
import edc_crf.model_mixins.crf_status_model_mixin
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
("meta_subject", "0205_historicalsubjectrequisition_crf_status_and_more"),
|
11
|
+
]
|
12
|
+
|
13
|
+
operations = [
|
14
|
+
migrations.AddField(
|
15
|
+
model_name="bloodresultsfbc",
|
16
|
+
name="crf_status",
|
17
|
+
field=models.CharField(
|
18
|
+
choices=[
|
19
|
+
("INCOMPLETE", "Incomplete (some data pending)"),
|
20
|
+
("COMPLETE", "Complete"),
|
21
|
+
],
|
22
|
+
default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
|
23
|
+
help_text="If some data is still pending, flag this CRF as incomplete",
|
24
|
+
max_length=25,
|
25
|
+
verbose_name="CRF status",
|
26
|
+
),
|
27
|
+
),
|
28
|
+
migrations.AddField(
|
29
|
+
model_name="bloodresultsfbc",
|
30
|
+
name="crf_status_comments",
|
31
|
+
field=models.TextField(
|
32
|
+
blank=True,
|
33
|
+
help_text="for example, why some data is still pending",
|
34
|
+
null=True,
|
35
|
+
verbose_name="Any comments related to status of this CRF",
|
36
|
+
),
|
37
|
+
),
|
38
|
+
migrations.AddField(
|
39
|
+
model_name="historicalbloodresultsfbc",
|
40
|
+
name="crf_status",
|
41
|
+
field=models.CharField(
|
42
|
+
choices=[
|
43
|
+
("INCOMPLETE", "Incomplete (some data pending)"),
|
44
|
+
("COMPLETE", "Complete"),
|
45
|
+
],
|
46
|
+
default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
|
47
|
+
help_text="If some data is still pending, flag this CRF as incomplete",
|
48
|
+
max_length=25,
|
49
|
+
verbose_name="CRF status",
|
50
|
+
),
|
51
|
+
),
|
52
|
+
migrations.AddField(
|
53
|
+
model_name="historicalbloodresultsfbc",
|
54
|
+
name="crf_status_comments",
|
55
|
+
field=models.TextField(
|
56
|
+
blank=True,
|
57
|
+
help_text="for example, why some data is still pending",
|
58
|
+
null=True,
|
59
|
+
verbose_name="Any comments related to status of this CRF",
|
60
|
+
),
|
61
|
+
),
|
62
|
+
]
|
meta_subject/models/__init__.py
CHANGED
@@ -11,8 +11,8 @@ from .complications import Complications
|
|
11
11
|
from .complications_glycemia import ComplicationsGlycemia
|
12
12
|
from .concomitant_medication import ConcomitantMedication
|
13
13
|
from .delivery import Delivery
|
14
|
+
from .diabetes import DmDiagnosis, DmDxResult, DmFollowup
|
14
15
|
from .diet_and_lifestyle import DietAndLifestyle
|
15
|
-
from .dm_referral_followup import DmReferralFollowup
|
16
16
|
from .egfr_drop_notification import EgfrDropNotification
|
17
17
|
from .eq5d3l import Eq5d3l
|
18
18
|
from .followup_examination import FollowupExamination
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
-
from edc_crf.model_mixins import CrfWithActionModelMixin
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin, CrfWithActionModelMixin
|
3
3
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
4
4
|
from edc_lab_panel.panels import fbc_panel
|
5
5
|
from edc_lab_results import BLOOD_RESULTS_FBC_ACTION
|
@@ -29,6 +29,7 @@ class BloodResultsFbc(
|
|
29
29
|
MchcModelMixin,
|
30
30
|
McvModelMixin,
|
31
31
|
BloodResultsModelMixin,
|
32
|
+
CrfStatusModelMixin,
|
32
33
|
BaseUuidModel,
|
33
34
|
):
|
34
35
|
action_name = BLOOD_RESULTS_FBC_ACTION
|
@@ -40,6 +41,6 @@ class BloodResultsFbc(
|
|
40
41
|
limit_choices_to={"panel__name": fbc_panel.name}, **requisition_fk_options
|
41
42
|
)
|
42
43
|
|
43
|
-
class Meta(CrfWithActionModelMixin.Meta, BaseUuidModel.Meta):
|
44
|
+
class Meta(CrfWithActionModelMixin.Meta, CrfStatusModelMixin.Meta, BaseUuidModel.Meta):
|
44
45
|
verbose_name = "Blood Result: FBC"
|
45
46
|
verbose_name_plural = "Blood Results: FBC"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
2
3
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
3
4
|
from edc_lab_panel.panels import hba1c_panel
|
4
5
|
from edc_lab_results import BLOOD_RESULTS_HBA1C_ACTION
|
@@ -13,6 +14,7 @@ class BloodResultsHba1c(
|
|
13
14
|
Hba1cModelMixin,
|
14
15
|
CrfWithRequisitionModelMixin,
|
15
16
|
BloodResultsModelMixin,
|
17
|
+
CrfStatusModelMixin,
|
16
18
|
BaseUuidModel,
|
17
19
|
):
|
18
20
|
action_name = BLOOD_RESULTS_HBA1C_ACTION
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
2
3
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
3
4
|
from edc_lab_panel.panels import insulin_panel
|
4
5
|
from edc_lab_results import BLOOD_RESULTS_INSULIN_ACTION
|
@@ -13,6 +14,7 @@ class BloodResultsIns(
|
|
13
14
|
InsulinModelMixin,
|
14
15
|
CrfWithRequisitionModelMixin,
|
15
16
|
BloodResultsModelMixin,
|
17
|
+
CrfStatusModelMixin,
|
16
18
|
BaseUuidModel,
|
17
19
|
):
|
18
20
|
action_name = BLOOD_RESULTS_INSULIN_ACTION
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
2
3
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
3
4
|
from edc_lab_panel.panels import lft_panel
|
4
5
|
from edc_lab_results import BLOOD_RESULTS_LFT_ACTION
|
@@ -26,6 +27,7 @@ class BloodResultsLft(
|
|
26
27
|
GgtModelMixin,
|
27
28
|
CrfWithRequisitionModelMixin,
|
28
29
|
BloodResultsModelMixin,
|
30
|
+
CrfStatusModelMixin,
|
29
31
|
BaseUuidModel,
|
30
32
|
):
|
31
33
|
action_name = BLOOD_RESULTS_LFT_ACTION
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
2
3
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
3
4
|
from edc_lab_panel.panels import lipids_panel
|
4
5
|
from edc_lab_results import BLOOD_RESULTS_LIPID_ACTION
|
@@ -22,6 +23,7 @@ class BloodResultsLipid(
|
|
22
23
|
CholModelMixin,
|
23
24
|
CrfWithRequisitionModelMixin,
|
24
25
|
BloodResultsModelMixin,
|
26
|
+
CrfStatusModelMixin,
|
25
27
|
BaseUuidModel,
|
26
28
|
):
|
27
29
|
action_name = BLOOD_RESULTS_LIPID_ACTION
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from django.db import models
|
2
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
2
3
|
from edc_egfr.model_mixins import EgfrModelMixin
|
3
4
|
from edc_lab.model_mixins import CrfWithRequisitionModelMixin, requisition_fk_options
|
4
5
|
from edc_lab_panel.panels import rft_panel
|
@@ -22,6 +23,7 @@ class BloodResultsRft(
|
|
22
23
|
UricAcidModelMixin,
|
23
24
|
CrfWithRequisitionModelMixin,
|
24
25
|
BloodResultsModelMixin,
|
26
|
+
CrfStatusModelMixin,
|
25
27
|
BaseUuidModel,
|
26
28
|
):
|
27
29
|
action_name = BLOOD_RESULTS_RFT_ACTION
|
@@ -0,0 +1,50 @@
|
|
1
|
+
from django.db import models
|
2
|
+
from edc_constants.choices import YES_NO
|
3
|
+
from edc_constants.constants import OTHER
|
4
|
+
from edc_model.models import BaseUuidModel
|
5
|
+
from edc_model_fields.fields import OtherCharField
|
6
|
+
|
7
|
+
from ...model_mixins import CrfModelMixin
|
8
|
+
|
9
|
+
DM_DX_CHOICES = (
|
10
|
+
("fbg_confirmed", "Any FBG >= 7.0 mmol/L (confirmed by OGTT)"),
|
11
|
+
("fbg_unconfirmed", "Any FBG >= 7.0 mmol/L (NOT confirmed by OGTT)"),
|
12
|
+
("ogtt_annaul", "Annual OGTT >= 11.1 mmol/L"),
|
13
|
+
("ogtt_unscheduled", "Any OGTT >= 11.1 mmol/L (excluding annual or used in confirmation)"),
|
14
|
+
(OTHER, "Other"),
|
15
|
+
)
|
16
|
+
|
17
|
+
|
18
|
+
class DmDiagnosis(CrfModelMixin, BaseUuidModel):
|
19
|
+
|
20
|
+
dx_date = models.DateField(verbose_name="Date of diagnosis")
|
21
|
+
|
22
|
+
dx_initiated_by = models.CharField(
|
23
|
+
verbose_name="What initiated the diagnosis",
|
24
|
+
max_length=25,
|
25
|
+
choices=DM_DX_CHOICES,
|
26
|
+
)
|
27
|
+
|
28
|
+
dx_initiated_by_other = OtherCharField()
|
29
|
+
|
30
|
+
dx_tmg = models.CharField(
|
31
|
+
verbose_name="Was this case discussed with the TMG?",
|
32
|
+
max_length=15,
|
33
|
+
choices=YES_NO,
|
34
|
+
)
|
35
|
+
|
36
|
+
dx_tmg_date = models.DateField(
|
37
|
+
verbose_name="If YES, provide the date of the TMG discussion", null=True, blank=True
|
38
|
+
)
|
39
|
+
|
40
|
+
dx_no_tmg_reason = models.TextField(
|
41
|
+
verbose_name="If NO, please explain why this case was not discussed with the TMG",
|
42
|
+
null=True,
|
43
|
+
blank=True,
|
44
|
+
)
|
45
|
+
|
46
|
+
comments = models.TextField(verbose_name="Any other comments", null=True, blank=True)
|
47
|
+
|
48
|
+
class Meta(CrfModelMixin.Meta, BaseUuidModel.Meta):
|
49
|
+
verbose_name = "Diabetes diagnosis"
|
50
|
+
verbose_name_plural = "Diabetes diagnosis"
|
@@ -0,0 +1,70 @@
|
|
1
|
+
from django.contrib.sites.managers import CurrentSiteManager as DjangoCurrentSiteManager
|
2
|
+
from django.db import models
|
3
|
+
from django.db.models import Manager
|
4
|
+
from edc_constants.constants import EQ
|
5
|
+
from edc_lab.choices import RESULT_QUANTIFIER
|
6
|
+
from edc_model.models import BaseUuidModel, HistoricalRecords
|
7
|
+
from edc_reportable import (
|
8
|
+
MILLIGRAMS_PER_DECILITER,
|
9
|
+
MILLIMOLES_PER_LITER,
|
10
|
+
MILLIMOLES_PER_LITER_DISPLAY,
|
11
|
+
PERCENT,
|
12
|
+
)
|
13
|
+
from edc_sites.model_mixins import SiteModelMixin
|
14
|
+
|
15
|
+
from .dm_diagnosis import DmDiagnosis
|
16
|
+
|
17
|
+
UTESTIDS = (("fbg", "FBG mmol/L"), ("ogtt", "OGTT mmol/L"), ("hba1c", "HbA1c %"))
|
18
|
+
UNITS = (
|
19
|
+
(MILLIGRAMS_PER_DECILITER, MILLIGRAMS_PER_DECILITER),
|
20
|
+
(MILLIMOLES_PER_LITER, MILLIMOLES_PER_LITER_DISPLAY),
|
21
|
+
(PERCENT, "%"),
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class DmDxResult(SiteModelMixin, BaseUuidModel):
|
26
|
+
"""A user inline model to capture results used in determining a diagnosis
|
27
|
+
of diabetes (in the context of this study).
|
28
|
+
|
29
|
+
Glucose values (FBG/OGTT) are in mmol/L.
|
30
|
+
"""
|
31
|
+
|
32
|
+
dm_diagnosis = models.ForeignKey(DmDiagnosis, on_delete=models.PROTECT)
|
33
|
+
|
34
|
+
report_date = models.DateField(verbose_name="Date")
|
35
|
+
|
36
|
+
utestid = models.CharField(
|
37
|
+
verbose_name="Test",
|
38
|
+
max_length=15,
|
39
|
+
choices=UTESTIDS,
|
40
|
+
)
|
41
|
+
|
42
|
+
quantifier = models.CharField(
|
43
|
+
max_length=10,
|
44
|
+
choices=RESULT_QUANTIFIER,
|
45
|
+
default=EQ,
|
46
|
+
)
|
47
|
+
|
48
|
+
value = models.DecimalField(max_digits=8, decimal_places=2)
|
49
|
+
|
50
|
+
units = models.CharField(
|
51
|
+
verbose_name="Units",
|
52
|
+
max_length=15,
|
53
|
+
choices=UNITS,
|
54
|
+
)
|
55
|
+
|
56
|
+
fasted = models.BooleanField(
|
57
|
+
verbose_name="Fasted?",
|
58
|
+
max_length=15,
|
59
|
+
default=False,
|
60
|
+
)
|
61
|
+
|
62
|
+
comment = models.CharField(max_length=35, null=True, blank=True)
|
63
|
+
|
64
|
+
objects = Manager()
|
65
|
+
on_site = DjangoCurrentSiteManager()
|
66
|
+
history = HistoricalRecords()
|
67
|
+
|
68
|
+
class Meta(BaseUuidModel.Meta):
|
69
|
+
verbose_name = "Diabetes diagnosis: Result"
|
70
|
+
verbose_name_plural = "Diabetes diagnosis: Results"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
2
2
|
from django.db import models
|
3
3
|
from django.utils.html import format_html
|
4
|
+
from edc_action_item.models import ActionItem
|
4
5
|
from edc_adherence.choices import MISSED_PILLS
|
5
6
|
from edc_constants.choices import YES_NO, YES_NO_NA
|
6
7
|
from edc_constants.constants import NOT_APPLICABLE, QUESTION_RETIRED
|
@@ -16,10 +17,14 @@ from meta_lists.models import (
|
|
16
17
|
MissedReferralReasons,
|
17
18
|
)
|
18
19
|
|
19
|
-
from
|
20
|
+
from ...constants import DM_FOLLOWUP_ACTION
|
21
|
+
from ...model_mixins import CrfWithActionModelMixin
|
20
22
|
|
21
23
|
|
22
|
-
class
|
24
|
+
class DmFollowup(CrfWithActionModelMixin, BaseUuidModel):
|
25
|
+
|
26
|
+
action_name = DM_FOLLOWUP_ACTION
|
27
|
+
|
23
28
|
referral_date = models.DateField(
|
24
29
|
verbose_name="Date of referral to diabetes clinic",
|
25
30
|
)
|
@@ -138,7 +143,7 @@ class DmReferralFollowup(CrfModelMixin, BaseUuidModel):
|
|
138
143
|
|
139
144
|
on_dm_medications = models.CharField(
|
140
145
|
verbose_name="Are you currently taking any drug therapy for diabetes?",
|
141
|
-
choices=
|
146
|
+
choices=YES_NO_NA,
|
142
147
|
max_length=25,
|
143
148
|
)
|
144
149
|
|
@@ -199,6 +204,13 @@ class DmReferralFollowup(CrfModelMixin, BaseUuidModel):
|
|
199
204
|
blank=True,
|
200
205
|
)
|
201
206
|
|
202
|
-
|
203
|
-
|
204
|
-
|
207
|
+
def save(self, *args, **kwargs):
|
208
|
+
self.action_item = ActionItem.objects.get(
|
209
|
+
subject_identifier=self.subject_identifier, action_type__name=self.action_name
|
210
|
+
)
|
211
|
+
self.action_identifier = self.action_item.action_identifier
|
212
|
+
super().save(*args, **kwargs)
|
213
|
+
|
214
|
+
class Meta(CrfWithActionModelMixin.Meta, BaseUuidModel.Meta):
|
215
|
+
verbose_name = "Diabetes follow-up after referral"
|
216
|
+
verbose_name_plural = "Diabetes follow-up after referral"
|
meta_subject/models/glucose.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from django.db import models
|
2
|
-
from django.utils.translation import gettext as _
|
3
2
|
from edc_constants.choices import YES_NO
|
4
|
-
from edc_constants.constants import
|
3
|
+
from edc_constants.constants import NOT_APPLICABLE
|
5
4
|
from edc_glucose.model_mixins import (
|
6
5
|
fasting_model_mixin_factory,
|
7
6
|
fbg_model_mixin_factory,
|
@@ -10,16 +9,10 @@ from edc_glucose.model_mixins import (
|
|
10
9
|
from edc_model.models import BaseUuidModel
|
11
10
|
from edc_utils import formatted_date
|
12
11
|
|
12
|
+
from ..choices import ENDPOINT_CHOICES
|
13
13
|
from ..constants import AMENDMENT_DATE
|
14
14
|
from ..model_mixins import CrfModelMixin
|
15
15
|
|
16
|
-
ENDPOINT_CHOICES = (
|
17
|
-
(YES, _(YES)),
|
18
|
-
(PENDING, _("No. A repeat FBG will be scheduled")),
|
19
|
-
(NO, _(NO)),
|
20
|
-
(NOT_APPLICABLE, _("Not applicable")),
|
21
|
-
)
|
22
|
-
|
23
16
|
|
24
17
|
class Glucose(
|
25
18
|
CrfModelMixin,
|
@@ -38,10 +31,7 @@ class Glucose(
|
|
38
31
|
ogtt_model_mixin_factory("ogtt"),
|
39
32
|
BaseUuidModel,
|
40
33
|
):
|
41
|
-
|
42
|
-
# TODO: move IFG to bloogresultglu. Use this form for OGTT only 27/01/2021
|
43
|
-
|
44
|
-
"""A user model to capture IFG and OGTT"""
|
34
|
+
"""A user model to capture FBG/RBG and OGTT"""
|
45
35
|
|
46
36
|
fbg_performed = models.CharField(
|
47
37
|
verbose_name="Was the FBG test performed?",
|
@@ -81,5 +71,5 @@ class Glucose(
|
|
81
71
|
)
|
82
72
|
|
83
73
|
class Meta(CrfModelMixin.Meta, BaseUuidModel.Meta):
|
84
|
-
verbose_name = "Glucose (
|
85
|
-
verbose_name_plural = "Glucose (
|
74
|
+
verbose_name = "Glucose (FBG/RBG, OGTT)"
|
75
|
+
verbose_name_plural = "Glucose (FBG/RBG, OGTT)"
|
@@ -1,70 +1,59 @@
|
|
1
|
-
from django.core.validators import MaxValueValidator, MinValueValidator
|
2
1
|
from django.db import models
|
3
|
-
from edc_constants.choices import
|
4
|
-
from edc_constants.constants import
|
5
|
-
from edc_glucose.
|
6
|
-
|
7
|
-
|
8
|
-
from edc_model.models import BaseUuidModel
|
9
|
-
from edc_model.validators import datetime_not_future
|
10
|
-
from edc_reportable import (
|
11
|
-
MILLIGRAMS_PER_DECILITER,
|
12
|
-
MILLIMOLES_PER_LITER,
|
13
|
-
MILLIMOLES_PER_LITER_DISPLAY,
|
2
|
+
from edc_constants.choices import YES_NO
|
3
|
+
from edc_constants.constants import NO
|
4
|
+
from edc_glucose.model_mixins import (
|
5
|
+
fasting_model_mixin_factory,
|
6
|
+
fbg_model_mixin_factory,
|
14
7
|
)
|
8
|
+
from edc_model.models import BaseUuidModel
|
15
9
|
|
16
10
|
from ..model_mixins import CrfModelMixin
|
17
11
|
|
18
12
|
|
19
|
-
class
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
class GlucoseFbg(
|
14
|
+
CrfModelMixin,
|
15
|
+
fasting_model_mixin_factory(
|
16
|
+
None,
|
17
|
+
fasting=models.CharField(
|
18
|
+
verbose_name="Has the participant fasted?",
|
19
|
+
max_length=15,
|
20
|
+
choices=YES_NO,
|
21
|
+
null=True,
|
22
|
+
blank=False,
|
23
|
+
help_text="As reported by patient",
|
26
24
|
),
|
27
|
-
decimal_places=2,
|
28
|
-
validators=[MinValueValidator(1.00), MaxValueValidator(GLUCOSE_HIGH_READING)],
|
29
|
-
exclude_attrs_for_reportable=True,
|
30
25
|
),
|
31
|
-
|
26
|
+
fbg_model_mixin_factory("fbg"),
|
27
|
+
BaseUuidModel,
|
32
28
|
):
|
33
|
-
fasting = models.CharField(
|
34
|
-
verbose_name="Was this fasting or non-fasting?",
|
35
|
-
max_length=25,
|
36
|
-
choices=FASTING_CHOICES,
|
37
|
-
null=True,
|
38
|
-
blank=False,
|
39
|
-
)
|
40
29
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
fbg_performed = models.CharField(
|
31
|
+
verbose_name="Was the FBG test performed?",
|
32
|
+
max_length=15,
|
33
|
+
choices=YES_NO,
|
45
34
|
)
|
46
35
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
class Meta:
|
54
|
-
abstract = True
|
55
|
-
|
36
|
+
fbg_not_performed_reason = models.CharField(
|
37
|
+
verbose_name="If NO, provide reason",
|
38
|
+
max_length=150,
|
39
|
+
null=True,
|
40
|
+
blank=True,
|
41
|
+
)
|
56
42
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
43
|
+
fasting_duration_estimated = models.CharField(
|
44
|
+
max_length=15,
|
45
|
+
default=NO,
|
46
|
+
editable=False,
|
47
|
+
help_text=(
|
48
|
+
"Set to YES for existing values before duration "
|
49
|
+
"question was added to the form, otherwise NO"
|
50
|
+
),
|
51
|
+
)
|
62
52
|
|
63
|
-
|
64
|
-
verbose_name="Result date and time",
|
65
|
-
validators=[datetime_not_future],
|
53
|
+
repeat_fbg_date = models.DateField(
|
66
54
|
null=True,
|
67
55
|
blank=True,
|
56
|
+
help_text="Date should be within 1 week of report date",
|
68
57
|
)
|
69
58
|
|
70
59
|
class Meta(CrfModelMixin.Meta, BaseUuidModel.Meta):
|
@@ -3,6 +3,7 @@ from django.db import models
|
|
3
3
|
from django.utils.translation import gettext as _
|
4
4
|
from edc_constants.choices import YES_NO
|
5
5
|
from edc_constants.constants import NOT_APPLICABLE
|
6
|
+
from edc_crf.model_mixins import SingletonCrfModelMixin
|
6
7
|
from edc_he.choices import RELATIONSHIP_CHOICES, STATUS
|
7
8
|
from edc_he.model_mixins import HouseholdModelMixin, income_model_mixin_factory
|
8
9
|
from edc_model.models import BaseUuidModel
|
@@ -21,6 +22,7 @@ class HealthEconomicsUpdate(
|
|
21
22
|
),
|
22
23
|
}
|
23
24
|
),
|
25
|
+
SingletonCrfModelMixin,
|
24
26
|
CrfModelMixin,
|
25
27
|
BaseUuidModel,
|
26
28
|
):
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
from edc_lab.managers import RequisitionManager as Manager # noqa
|
1
|
+
from edc_crf.model_mixins import CrfStatusModelMixin
|
3
2
|
from edc_lab.model_mixins import RequisitionModelMixin
|
4
3
|
from edc_model.models import BaseUuidModel
|
5
4
|
|
6
5
|
|
7
|
-
class SubjectRequisition(RequisitionModelMixin, BaseUuidModel):
|
8
|
-
class Meta(RequisitionModelMixin.Meta, BaseUuidModel.Meta):
|
6
|
+
class SubjectRequisition(RequisitionModelMixin, CrfStatusModelMixin, BaseUuidModel):
|
7
|
+
class Meta(RequisitionModelMixin.Meta, CrfStatusModelMixin.Meta, BaseUuidModel.Meta):
|
9
8
|
pass
|
@@ -9,7 +9,7 @@ import time_machine
|
|
9
9
|
from django import forms
|
10
10
|
from django.conf import settings
|
11
11
|
from django.contrib.sites.models import Site
|
12
|
-
from django.test import TestCase
|
12
|
+
from django.test import TestCase
|
13
13
|
from edc_action_item import site_action_items
|
14
14
|
from edc_action_item.models import ActionItem
|
15
15
|
from edc_constants.constants import BLACK, MALE
|
@@ -18,7 +18,7 @@ from edc_lab.models import Panel
|
|
18
18
|
from edc_lab_results import BLOOD_RESULTS_EGFR_ACTION, BLOOD_RESULTS_RFT_ACTION
|
19
19
|
from edc_registration import get_registered_subject_model_cls
|
20
20
|
from edc_reportable import MICROMOLES_PER_LITER, MILLIGRAMS_PER_DECILITER
|
21
|
-
from edc_utils import age
|
21
|
+
from edc_utils import age, get_utcnow
|
22
22
|
from edc_utils.round_up import round_half_away_from_zero
|
23
23
|
from edc_visit_schedule.constants import OFFSCHEDULE_ACTION
|
24
24
|
|
@@ -37,7 +37,7 @@ from meta_subject.models import (
|
|
37
37
|
@time_machine.travel(datetime(2019, 6, 11, 8, 00, tzinfo=ZoneInfo("UTC")))
|
38
38
|
class TestEgfr(MetaTestCaseMixin, TestCase):
|
39
39
|
def setUp(self):
|
40
|
-
self.subject_visit = self.get_subject_visit()
|
40
|
+
self.subject_visit = self.get_subject_visit(screening_datetime=get_utcnow())
|
41
41
|
panel = Panel.objects.get(name="chemistry_rft")
|
42
42
|
requisition = SubjectRequisition.objects.create(
|
43
43
|
subject_visit=self.subject_visit,
|
@@ -62,11 +62,12 @@ class TestEgfr(MetaTestCaseMixin, TestCase):
|
|
62
62
|
self.assertIsNotNone(obj.egfr_value)
|
63
63
|
self.assertIsNotNone(obj.egfr_units)
|
64
64
|
|
65
|
-
@tag("3")
|
66
65
|
def test_ok(self):
|
66
|
+
traveller = time_machine.travel(self.subject_visit.report_datetime)
|
67
|
+
traveller.start()
|
67
68
|
data = dict(
|
68
69
|
subject_visit=self.subject_visit,
|
69
|
-
report_datetime=
|
70
|
+
report_datetime=get_utcnow(),
|
70
71
|
)
|
71
72
|
form = BloodResultsRftFormValidator(cleaned_data=data, model=BloodResultsRft)
|
72
73
|
try:
|