Skip to content

Commit

Permalink
Merge pull request #509 from UW-GAC/feature/cdsa-requires-study-review
Browse files Browse the repository at this point in the history
Add a requires_study_review field for DataAffiliateAgreements
  • Loading branch information
amstilp authored Mar 21, 2024
2 parents 8ee1eee + 37d47e9 commit 1a713f0
Show file tree
Hide file tree
Showing 25 changed files with 1,245 additions and 452 deletions.
32 changes: 23 additions & 9 deletions add_cdsa_example_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
# Load duos
call_command("load_duo")

# create the CDSA auth group
cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME)
# Add PRIMED ADMINS group
cc_admins_group = ManagedGroupFactory.create(name=settings.ANVIL_CC_ADMINS_GROUP_NAME)

# Create major versions
major_version = factories.AgreementMajorVersionFactory.create(version=1)

Expand All @@ -35,9 +40,6 @@
dup = DataUsePermission.objects.get(abbreviation="GRU")
dum = DataUseModifier.objects.get(abbreviation="NPU")

# create the CDSA auth group
cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME)

# Create some study sites.
StudySiteFactory.create(short_name="CC", full_name="Coordinating Center")
StudySiteFactory.create(short_name="CARDINAL", full_name="CARDINAL")
Expand All @@ -51,7 +53,7 @@
signed_agreement__representative=UserFactory.create(name="Ken Rice"),
signed_agreement__signing_institution="UW",
signed_agreement__representative_role="Contact PI",
signed_agreement__is_primary=True,
is_primary=True,
signed_agreement__version=v10,
study_site=StudySite.objects.get(short_name="CC"),
)
Expand All @@ -64,7 +66,7 @@
signed_agreement__representative=UserFactory.create(name="Sally Adebamowo"),
signed_agreement__signing_institution="UM",
signed_agreement__representative_role="Contact PI",
signed_agreement__is_primary=True,
is_primary=True,
signed_agreement__version=v10,
study_site=StudySite.objects.get(short_name="CARDINAL"),
)
Expand All @@ -77,7 +79,7 @@
signed_agreement__representative=UserFactory.create(name="Bamidele Tayo"),
signed_agreement__signing_institution="Loyola",
signed_agreement__representative_role="Co-PI",
signed_agreement__is_primary=False,
is_primary=False,
signed_agreement__version=v10,
study_site=StudySite.objects.get(short_name="CARDINAL"),
)
Expand All @@ -90,7 +92,7 @@
signed_agreement__representative=UserFactory.create(name="Brackie Mitchell"),
signed_agreement__signing_institution="UM",
signed_agreement__representative_role="Co-I",
signed_agreement__is_primary=False,
is_primary=False,
signed_agreement__version=v11,
study_site=StudySite.objects.get(short_name="CARDINAL"),
)
Expand Down Expand Up @@ -118,6 +120,7 @@
study=Study.objects.get(short_name="MESA"),
signed_agreement__version=v10,
additional_limitations="This data can only be used for testing the app.",
requires_study_review=True,
)
GroupGroupMembershipFactory.create(
parent_group=cdsa_group, child_group=cdsa_1006.signed_agreement.anvil_access_group
Expand All @@ -128,7 +131,7 @@
signed_agreement__representative=UserFactory.create(name="Wendy"),
signed_agreement__signing_institution="JHU",
signed_agreement__representative_role="Field Center PI",
signed_agreement__is_primary=False,
is_primary=False,
study=Study.objects.get(short_name="MESA"),
signed_agreement__version=v10,
)
Expand All @@ -141,7 +144,7 @@
signed_agreement__representative=UserFactory.create(name="Jerry"),
signed_agreement__signing_institution="Lundquist",
signed_agreement__representative_role="Analysis Center PI",
signed_agreement__is_primary=False,
is_primary=False,
study=Study.objects.get(short_name="MESA"),
signed_agreement__version=v10,
)
Expand Down Expand Up @@ -227,3 +230,14 @@
additional_limitations="Additional limitations for workspace.",
)
cdsa_workspace_2.data_use_modifiers.add(dum)


# Add a workspace with no primary cdsa.
cdsa_workspace_3 = factories.CDSAWorkspaceFactory.create(
workspace__billing_project__name="demo-primed-cdsa",
workspace__name="DEMO_PRIMED_CDSA_ARIC_1",
study=Study.objects.create(
short_name="ARIC", full_name="Atherosclerosis Risk in Communities"
),
data_use_permission=dup,
)
10 changes: 5 additions & 5 deletions primed/cdsa/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ class SignedAgreement(SimpleHistoryAdmin):
"cc_id",
"representative",
"type",
"is_primary",
# "is_primary",
"date_signed",
"version",
)
list_filter = (
"type",
"is_primary",
# "is_primary",
"version",
"status",
)
Expand All @@ -79,7 +79,7 @@ class MemberAgreementAdmin(SimpleHistoryAdmin):
)
list_filter = (
"study_site",
"signed_agreement__is_primary",
# "signed_agreement__is_primary",
"signed_agreement__status",
)

Expand All @@ -94,7 +94,7 @@ class DataAffiliateAgreementAdmin(SimpleHistoryAdmin):
)
list_filter = (
"study",
"signed_agreement__is_primary",
# "signed_agreement__is_primary",
"signed_agreement__status",
)

Expand All @@ -108,7 +108,7 @@ class NonDataAffiliateAgreementAdmin(SimpleHistoryAdmin):
"affiliation",
)
list_filter = (
"signed_agreement__is_primary",
# "signed_agreement__is_primary",
"signed_agreement__status",
)

Expand Down
18 changes: 4 additions & 14 deletions primed/cdsa/audit/signed_agreement_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@ class SignedAgreementAccessAudit(PRIMEDAudit):
PRIMARY_NOT_ACTIVE = "Primary agreement for this CDSA is not active."

# Other errors
ERROR_NON_DATA_AFFILIATE_COMPONENT = (
"Non-data affiliate agreements must be primary."
)
ERROR_OTHER_CASE = "Signed Agreement did not match any expected situations."

results_table_class = SignedAgreementAccessAuditTable
Expand Down Expand Up @@ -218,23 +215,15 @@ def _audit_component_agreement(self, signed_agreement):
if hasattr(signed_agreement, "memberagreement"):
# Member
primary_qs = models.SignedAgreement.objects.filter(
is_primary=True,
memberagreement__is_primary=True,
memberagreement__study_site=signed_agreement.memberagreement.study_site,
)
elif hasattr(signed_agreement, "dataaffiliateagreement"):
# Data affiliate
primary_qs = models.SignedAgreement.objects.filter(
is_primary=True,
dataaffiliateagreement__is_primary=True,
dataaffiliateagreement__study=signed_agreement.dataaffiliateagreement.study,
)
elif hasattr(signed_agreement, "nondataaffiliateagreement"):
self.errors.append(
OtherError(
signed_agreement=signed_agreement,
note=self.ERROR_NON_DATA_AFFILIATE_COMPONENT,
)
)
return
primary_exists = primary_qs.exists()
primary_active = primary_qs.filter(
status=models.SignedAgreement.StatusChoices.ACTIVE,
Expand Down Expand Up @@ -320,7 +309,8 @@ def _audit_component_agreement(self, signed_agreement):
) # pragma: no cover

def _audit_signed_agreement(self, signed_agreement):
if signed_agreement.is_primary:
agreement_type = signed_agreement.get_agreement_type()
if not hasattr(agreement_type, "is_primary") or agreement_type.is_primary:
self._audit_primary_agreement(signed_agreement)
else:
self._audit_component_agreement(signed_agreement)
Expand Down
2 changes: 1 addition & 1 deletion primed/cdsa/audit/workspace_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _audit_workspace(self, workspace):
child_group=self.anvil_cdsa_group,
).exists()
primary_qs = models.DataAffiliateAgreement.objects.filter(
study=workspace.study, signed_agreement__is_primary=True
study=workspace.study, is_primary=True
)
primary_exists = primary_qs.exists()

Expand Down
24 changes: 17 additions & 7 deletions primed/cdsa/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ class Meta:
class SignedAgreementForm(Bootstrap5MediaFormMixin, forms.ModelForm):
"""Form for a SignedAgreement object."""

is_primary = forms.TypedChoiceField(
coerce=lambda x: x == "True",
choices=((True, "Primary"), (False, "Component")),
widget=forms.RadioSelect,
label="Agreement type",
)
version = forms.ModelChoiceField(
queryset=models.AgreementVersion.objects.filter(major_version__is_valid=True)
)
Expand All @@ -41,7 +35,6 @@ class Meta:
"signing_institution",
"version",
"date_signed",
"is_primary",
)
widgets = {
"representative": autocomplete.ModelSelect2(
Expand All @@ -63,21 +56,38 @@ class Meta:


class MemberAgreementForm(forms.ModelForm):
is_primary = forms.TypedChoiceField(
coerce=lambda x: x == "True",
choices=((True, "Primary"), (False, "Component")),
widget=forms.RadioSelect,
label="Agreement type",
)

class Meta:
model = models.MemberAgreement
fields = (
"signed_agreement",
"study_site",
"is_primary",
)


class DataAffiliateAgreementForm(Bootstrap5MediaFormMixin, forms.ModelForm):
is_primary = forms.TypedChoiceField(
coerce=lambda x: x == "True",
choices=((True, "Primary"), (False, "Component")),
widget=forms.RadioSelect,
label="Agreement type",
)

class Meta:
model = models.DataAffiliateAgreement
fields = (
"signed_agreement",
"study",
"is_primary",
"additional_limitations",
"requires_study_review",
)
widgets = {
"study": autocomplete.ModelSelect2(
Expand Down
2 changes: 1 addition & 1 deletion primed/cdsa/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def get_study_records_table():
"""Return the queryset for study records."""
qs = models.DataAffiliateAgreement.objects.filter(
signed_agreement__status=models.SignedAgreement.StatusChoices.ACTIVE,
signed_agreement__is_primary=True,
is_primary=True,
)
return tables.StudyRecordsTable(qs)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.10 on 2024-03-15 20:48

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("cdsa", "0017_alter_cdsaworkspace_additional_limitations_and_more"),
]

operations = [
migrations.AddField(
model_name="dataaffiliateagreement",
name="requires_study_review",
field=models.BooleanField(
default=False,
help_text="Indicator of whether indicates investigators need to have an approved PRIMED paper proposal where this dataset was selected and approved in order to work with data brought under this CDSA.",
),
),
migrations.AddField(
model_name="historicaldataaffiliateagreement",
name="requires_study_review",
field=models.BooleanField(
default=False,
help_text="Indicator of whether indicates investigators need to have an approved PRIMED paper proposal where this dataset was selected and approved in order to work with data brought under this CDSA.",
),
),
]
29 changes: 29 additions & 0 deletions primed/cdsa/migrations/0019_alter_signedagreement_is_primary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.10 on 2024-03-18 17:24

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("cdsa", "0018_dataaffiliateagreement_requires_study_review_and_more"),
]

operations = [
migrations.AlterField(
model_name="historicalsignedagreement",
name="is_primary",
field=models.BooleanField(
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
null=True,
),
),
migrations.AlterField(
model_name="signedagreement",
name="is_primary",
field=models.BooleanField(
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
null=True,
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Generated by Django 4.2.10 on 2024-03-15 22:43

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("cdsa", "0019_alter_signedagreement_is_primary"),
]

operations = [
migrations.AddField(
model_name="dataaffiliateagreement",
name="is_primary",
field=models.BooleanField(
default=False,
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
),
preserve_default=False,
),
migrations.AddField(
model_name="historicaldataaffiliateagreement",
name="is_primary",
field=models.BooleanField(
default=False,
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
),
preserve_default=False,
),
migrations.AddField(
model_name="historicalmemberagreement",
name="is_primary",
field=models.BooleanField(
default=False,
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
),
preserve_default=False,
),
migrations.AddField(
model_name="memberagreement",
name="is_primary",
field=models.BooleanField(
default=False,
help_text="Indicator of whether this is a primary Agreement (and not a component Agreement).",
),
preserve_default=False,
),
]
Loading

0 comments on commit 1a713f0

Please sign in to comment.