diff --git a/amy/extforms/tests/test_selforganised_submission_form.py b/amy/extforms/tests/test_selforganised_submission_form.py index b641d6d37..d7a9e1650 100644 --- a/amy/extforms/tests/test_selforganised_submission_form.py +++ b/amy/extforms/tests/test_selforganised_submission_form.py @@ -27,8 +27,6 @@ def test_fields_presence(self): "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", - "member_code", "workshop_format", "workshop_format_other", "start", diff --git a/amy/extforms/tests/test_workshop_inquiry_form.py b/amy/extforms/tests/test_workshop_inquiry_form.py index ec8ae4748..b4e1e6cec 100644 --- a/amy/extforms/tests/test_workshop_inquiry_form.py +++ b/amy/extforms/tests/test_workshop_inquiry_form.py @@ -25,8 +25,6 @@ def test_fields_presence(self): "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", - "member_code", "location", "country", "routine_data", diff --git a/amy/extforms/tests/test_workshop_request_form.py b/amy/extforms/tests/test_workshop_request_form.py index 74524d68b..becfc3524 100644 --- a/amy/extforms/tests/test_workshop_request_form.py +++ b/amy/extforms/tests/test_workshop_request_form.py @@ -24,7 +24,6 @@ def test_fields_presence(self): "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", "member_code", "location", "country", diff --git a/amy/extrequests/forms.py b/amy/extrequests/forms.py index 74694677f..498b4bce9 100644 --- a/amy/extrequests/forms.py +++ b/amy/extrequests/forms.py @@ -302,7 +302,6 @@ class Meta: "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", "member_code", "location", "country", @@ -389,11 +388,6 @@ def __init__(self, *args, **kwargs): (self["institution_other_URL"], "Institution URL address"), ] - # move "member_code" field to "member_affiliation" subfield - self["member_affiliation"].field.widget.subfields = [ - (self["member_code"], "Member registration code"), - ] - # remove additional fields self.helper.layout.fields.remove("travel_expences_management_other") self.helper.layout.fields.remove("public_event_other") @@ -401,7 +395,6 @@ def __init__(self, *args, **kwargs): self.helper.layout.fields.remove("carpentries_info_source_other") self.helper.layout.fields.remove("institution_other_name") self.helper.layout.fields.remove("institution_other_URL") - self.helper.layout.fields.remove("member_code") # add warning alert for dates falling within next 2-3 months DATES_TOO_SOON_WARNING = ( @@ -429,7 +422,7 @@ def __init__(self, *args, **kwargs): hr_fields_after = ( "secondary_email", "institution_department", - "member_affiliation", + "member_code", "country", "audience_description", "user_notes", @@ -458,25 +451,16 @@ def validate_member_code( self, request: HttpRequest ) -> None | dict[str, ValidationError]: errors = dict() - affiliation = self.cleaned_data.get("member_affiliation") # yes/no/unsure code = self.cleaned_data.get("member_code", "") - if affiliation in ["yes", "unsure"] and code: - # ensure that code belongs to a membership - try: - Membership.objects.get(registration_code=code) - except Membership.DoesNotExist: - errors["member_code"] = ValidationError( - "This code is invalid. " - "Please contact your Member Affiliate to verify your code." - ) - elif affiliation == "yes" and not code: - errors["member_code"] = ValidationError( - "This field is required if you selected 'Yes' above." - ) - elif affiliation == "no" and code: - errors["member_code"] = ValidationError( - "This field must be empty if you selected 'No' above." - ) + error_msg = ( + "This code is invalid. " + "Please contact your Member Affiliate to verify your code." + ) + # ensure that code belongs to a membership + try: + Membership.objects.get(registration_code=code) + except Membership.DoesNotExist: + errors["member_code"] = ValidationError(error_msg) return errors @@ -745,8 +729,6 @@ class Meta: "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", - "member_code", "location", "country", "online_inperson", @@ -899,7 +881,6 @@ def __init__(self, *args, **kwargs): hr_fields_after = ( "secondary_email", "institution_department", - "member_code", "audience_description", "country", "user_notes", @@ -1165,8 +1146,6 @@ class Meta: "institution_other_name", "institution_other_URL", "institution_department", - "member_affiliation", - "member_code", "online_inperson", "workshop_format", "workshop_format_other", @@ -1243,7 +1222,6 @@ def __init__(self, *args, **kwargs): hr_fields_after = ( "secondary_email", "institution_department", - "member_code", "additional_contact", "language", "online_inperson", diff --git a/amy/extrequests/migrations/0033_auto_20231023_1345.py b/amy/extrequests/migrations/0033_auto_20231023_1345.py new file mode 100644 index 000000000..9b00d043d --- /dev/null +++ b/amy/extrequests/migrations/0033_auto_20231023_1345.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.20 on 2023-10-23 13:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extrequests', '0032_add_member_affiliation_and_member_code'), + ] + + operations = [ + migrations.RemoveField( + model_name='selforganisedsubmission', + name='member_affiliation', + ), + migrations.RemoveField( + model_name='workshopinquiryrequest', + name='member_affiliation', + ), + ] diff --git a/amy/extrequests/tests/test_selforganised_submissions.py b/amy/extrequests/tests/test_selforganised_submissions.py index 3753ac04f..d4a047e07 100644 --- a/amy/extrequests/tests/test_selforganised_submissions.py +++ b/amy/extrequests/tests/test_selforganised_submissions.py @@ -11,16 +11,7 @@ from extrequests.models import SelfOrganisedSubmission import extrequests.views from workshops.forms import EventCreateForm -from workshops.models import ( - Curriculum, - Event, - Language, - Membership, - Organization, - Role, - Tag, - Task, -) +from workshops.models import Curriculum, Event, Language, Organization, Role, Tag, Task from workshops.tests.base import FormTestHelper, TestBase @@ -353,12 +344,6 @@ def test_accept_with_event_autofill(self): """Ensure that fields are autofilled correctly when creating an Event from a SelfOrganisedSubmission.""" # Arrange - expected_membership = Membership.objects.create( - name="Hogwarts", - agreement_start=date.today() - timedelta(weeks=26), - agreement_end=date.today() + timedelta(weeks=26), - registration_code="hogwarts55", - ) sos = SelfOrganisedSubmission.objects.create( # required fields state="p", @@ -374,8 +359,6 @@ def test_accept_with_event_autofill(self): online_inperson="online", workshop_listed=False, additional_contact="hermione@granger.com", - member_affiliation="yes", - member_code="hogwarts55", ) curriculum = Curriculum.objects.filter(name__contains="Data Carpentry").first() sos.workshop_types.set([curriculum]) @@ -399,7 +382,6 @@ def test_accept_with_event_autofill(self): self.assertEqual(form_initial["host"].pk, sos.institution.pk) self.assertEqual(form_initial["start"], sos.start) self.assertEqual(form_initial["end"], sos.end) - self.assertEqual(form_initial["membership"].pk, expected_membership.pk) def test_discarded_request_not_accepted_with_event(self): rv = self.client.get( diff --git a/amy/extrequests/tests/test_workshop_inquiries.py b/amy/extrequests/tests/test_workshop_inquiries.py index 7dea435a9..4fb9fb9f1 100644 --- a/amy/extrequests/tests/test_workshop_inquiries.py +++ b/amy/extrequests/tests/test_workshop_inquiries.py @@ -16,7 +16,6 @@ Event, KnowledgeDomain, Language, - Membership, Organization, Role, Tag, @@ -511,12 +510,6 @@ def test_accept_with_event_autofill(self): """Ensure that fields are autofilled correctly when creating an Event from a WorkshopInquiryRequest.""" # Arrange - expected_membership = Membership.objects.create( - name="Hogwarts", - agreement_start=date.today() - timedelta(weeks=26), - agreement_end=date.today() + timedelta(weeks=26), - registration_code="hogwarts55", - ) wi = WorkshopInquiryRequest.objects.create( # required fields state="p", @@ -535,8 +528,6 @@ def test_accept_with_event_autofill(self): online_inperson="online", workshop_listed=False, additional_contact="hermione@granger.com", - member_affiliation="yes", - member_code="hogwarts55", ) curriculum = Curriculum.objects.filter(name__contains="Data Carpentry").first() wi.requested_workshop_types.set([curriculum]) @@ -558,7 +549,6 @@ def test_accept_with_event_autofill(self): self.assertEqual(form_initial["host"].pk, wi.institution.pk) self.assertEqual(form_initial["start"], wi.preferred_dates) self.assertEqual(form_initial["end"], wi.preferred_dates + timedelta(days=1)) - self.assertEqual(form_initial["membership"].pk, expected_membership.pk) def test_discarded_request_not_accepted_with_event(self): rv = self.client.get( diff --git a/amy/extrequests/tests/test_workshop_requests.py b/amy/extrequests/tests/test_workshop_requests.py index a18e67b1a..2de7e9455 100644 --- a/amy/extrequests/tests/test_workshop_requests.py +++ b/amy/extrequests/tests/test_workshop_requests.py @@ -45,7 +45,6 @@ def test_minimal_form(self): "email": "hpotter@magic.gov", "institution_other_name": "Ministry of Magic", "institution_other_URL": "magic.gov.uk", - "member_affiliation": "no", "member_code": "", "location": "London", "country": "GB", @@ -364,14 +363,7 @@ class TestWorkshopRequestCreateView(TestBase): All other form validation is tested in the TestWorkshopRequestBaseForm class above. """ - INVALID_CODE_ERROR = ( - "This code is invalid. " - "Please contact your Member Affiliate to verify your code." - ) - MUST_ENTER_CODE = "This field is required if you selected 'Yes' above." - MUST_NOT_ENTER_CODE = ( - "This field must be empty if you selected 'No' above." - ) + INVALID_CODE_ERROR = "This code is invalid." def setUp(self): super().setUp() @@ -389,12 +381,11 @@ def setUpMembership(self): ) @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_yes_code_valid(self): - # 1: affiliation "yes" and valid code - no error + def test_member_code_validation__code_valid(self): + """valid code - no error""" # Arrange self.setUpMembership() data = { - "member_affiliation": "yes", "member_code": "valid123", } @@ -404,15 +395,12 @@ def test_member_code_validation__affiliation_yes_code_valid(self): # Assert self.assertEqual(rv.status_code, 200) self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_yes_code_invalid(self): - # 2: affiliation "yes" and invalid code - error on code + def test_member_code_validation__code_no_match(self): + """code does not match a membership - error on code""" # Arrange data = { - "member_affiliation": "yes", "member_code": "invalid", } @@ -422,15 +410,12 @@ def test_member_code_validation__affiliation_yes_code_invalid(self): # Assert self.assertEqual(rv.status_code, 200) self.assertContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_yes_code_empty(self): - # 3: affiliation "yes" and empty code - error on code + def test_member_code_validation_code_empty(self): + """empty code - no error""" # Arrange data = { - "member_affiliation": "yes", "member_code": "", } @@ -439,102 +424,6 @@ def test_member_code_validation__affiliation_yes_code_empty(self): # Assert self.assertEqual(rv.status_code, 200) - self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertIn(self.MUST_ENTER_CODE, rv.content.decode("utf-8")) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) - - @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_unsure_code_valid(self): - self.setUpMembership() - # 4: affiliation "unsure" and valid code - no error - # Arrange - data = { - "member_affiliation": "yes", - "member_code": "valid123", - } - - # Act - rv = self.client.post(reverse("workshop_request"), data=data) - - # Assert - self.assertEqual(rv.status_code, 200) - self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) - - @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_unsure_code_invalid(self): - # 5: affiliation "unsure" and invalid code - error on code - # Arrange - data = { - "member_affiliation": "unsure", - "member_code": "invalid", - } - - # Act - rv = self.client.post(reverse("workshop_request"), data=data) - - # Assert - self.assertEqual(rv.status_code, 200) - self.assertContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) - - @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_unsure_code_empty(self): - # 6: affiliation "unsure" and empty code - no error - # Arrange - data = { - "member_affiliation": "unsure", - "member_code": "", - } - - # Act - rv = self.client.post(reverse("workshop_request"), data=data) - - # Assert - self.assertEqual(rv.status_code, 200) - self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) - - @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_no_code_not_empty(self): - # 7: affiliation "no" and non-empty code - error on code - # even if a valid code is entered, an error is produced - # Arrange - self.setUpMembership() - data = { - "member_affiliation": "no", - "member_code": "valid123", - } - - # Act - rv = self.client.post(reverse("workshop_request"), data=data) - - # Assert - self.assertEqual(rv.status_code, 200) - self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertContains(rv, self.MUST_NOT_ENTER_CODE) - - @override_settings(FLAGS={"ENFORCE_MEMBER_CODES": [("boolean", True)]}) - def test_member_code_validation__affiliation_no_code_empty(self): - # 8: affiliation "no" and empty code - no error - # Arrange - data = { - "member_affiliation": "no", - "member_code": "", - } - - # Act - rv = self.client.post(reverse("workshop_request"), data=data) - - # Assert - self.assertEqual(rv.status_code, 200) - self.assertNotContains(rv, self.INVALID_CODE_ERROR) - self.assertNotContains(rv, self.MUST_ENTER_CODE) - self.assertNotContains(rv, self.MUST_NOT_ENTER_CODE) class TestWorkshopRequestViews(TestBase): @@ -663,7 +552,6 @@ def test_accept_with_event_autofill(self): online_inperson="online", workshop_listed=False, additional_contact="hermione@granger.com", - member_affiliation="yes", member_code="hogwarts55", ) curriculum = Curriculum.objects.filter(name__contains="Data Carpentry").first() diff --git a/amy/templates/includes/selforganisedsubmission_details.html b/amy/templates/includes/selforganisedsubmission_details.html index 32108c533..16878a9b8 100644 --- a/amy/templates/includes/selforganisedsubmission_details.html +++ b/amy/templates/includes/selforganisedsubmission_details.html @@ -29,14 +29,6 @@ {% include "includes/request_institution.html" with admin=admin object=object %} - Affiliated with a member? - - {{ object.member_affiliation|default:"—" }} - - Member registration code: - - {{ object.member_code|default:"—" }} - Online or Inperson: {{ object.online_inperson }} diff --git a/amy/templates/includes/workshopinquiry_details.html b/amy/templates/includes/workshopinquiry_details.html index 9c49fad9c..fbf51716c 100644 --- a/amy/templates/includes/workshopinquiry_details.html +++ b/amy/templates/includes/workshopinquiry_details.html @@ -29,14 +29,6 @@ {% include "includes/request_institution.html" with admin=admin object=object %} - Affiliated with a member? - - {{ object.member_affiliation|default:"—" }} - - Member registration code: - - {{ object.member_code|default:"—" }} - Workshop location: {{ object.location }} Country: diff --git a/amy/templates/includes/workshoprequest_details.html b/amy/templates/includes/workshoprequest_details.html index 6b03da5cd..944441765 100644 --- a/amy/templates/includes/workshoprequest_details.html +++ b/amy/templates/includes/workshoprequest_details.html @@ -29,10 +29,6 @@ {% include "includes/request_institution.html" with admin=admin object=object %} - Affiliated with a member? - - {{ object.member_affiliation|default:"—" }} - Member registration code: {{ object.member_code|default:"—" }} diff --git a/amy/workshops/management/commands/fake_database.py b/amy/workshops/management/commands/fake_database.py index 66a630f0d..eefdae50f 100644 --- a/amy/workshops/management/commands/fake_database.py +++ b/amy/workshops/management/commands/fake_database.py @@ -625,19 +625,19 @@ def fake_duplicated_people(self, count=5): p.save() def get_or_invent_member_code(self): - member_affiliation = choice(WorkshopRequest.MEMBER_AFFILIATION_CHOICES)[0] - member_code = "" - if member_affiliation != "no": - if randbool(0.75): - # 75% of time, use an existing member code - # may or may not be a valid choice depending on membership dates - membership = choice(Membership.objects.all()) - member_code = membership.registration_code - else: - # 25% of time, make up an invalid code - member_code = self.faker.word() + if randbool(0.5): + # 50% of time, use an existing member code + # may or may not be a valid choice depending on membership dates + membership = choice(Membership.objects.all()) + member_code = membership.registration_code + elif randbool(0.5): + # 25% of time, make up an invalid code + member_code = self.faker.word() + else: + # 25% of time, don't use any code + member_code = "" - return member_affiliation, member_code + return member_code def fake_workshop_requests(self, count=10): self.stdout.write("Generating {} fake " "workshop requests...".format(count)) @@ -682,7 +682,7 @@ def fake_workshop_requests(self, count=10): self.faker.sentence() if institution_restrictions == "" else "" ) - member_affiliation, member_code = self.get_or_invent_member_code() + member_code = self.get_or_invent_member_code() req = WorkshopRequest.objects.create( state=choice(["p", "d", "a"]), data_privacy_agreement=randbool(0.5), @@ -695,7 +695,6 @@ def fake_workshop_requests(self, count=10): institution_other_name=org_name, institution_other_URL=org_url, institution_department="", - member_affiliation=member_affiliation, member_code=member_code, online_inperson=online_inperson, public_event=public_event, @@ -769,8 +768,6 @@ def fake_workshop_inquiries(self, count=10): self.faker.sentence() if institution_restrictions == "" else "" ) - member_affiliation, member_code = self.get_or_invent_member_code() - req = WorkshopInquiryRequest.objects.create( state=choice(["p", "d", "a"]), data_privacy_agreement=randbool(0.5), @@ -783,8 +780,6 @@ def fake_workshop_inquiries(self, count=10): institution_other_name=org_name, institution_other_URL=org_url, institution_department="", - member_affiliation=member_affiliation, - member_code=member_code, online_inperson=online_inperson, public_event=public_event, public_event_other=public_event_other, @@ -863,8 +858,6 @@ def fake_selforganised_submissions(self, count=10): workshop_types = sample(curricula) workshop_types_explain = "" - member_affiliation, member_code = self.get_or_invent_member_code() - req = SelfOrganisedSubmission.objects.create( state=choice(["p", "d", "a"]), data_privacy_agreement=randbool(0.5), @@ -877,8 +870,6 @@ def fake_selforganised_submissions(self, count=10): institution_other_name=org_name, institution_other_URL=org_url, institution_department="", - member_affiliation=member_affiliation, - member_code=member_code, online_inperson=online_inperson, public_event=public_event, public_event_other=public_event_other, diff --git a/amy/workshops/migrations/0268_remove_workshoprequest_member_affiliation.py b/amy/workshops/migrations/0268_remove_workshoprequest_member_affiliation.py new file mode 100644 index 000000000..ce8a82067 --- /dev/null +++ b/amy/workshops/migrations/0268_remove_workshoprequest_member_affiliation.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.20 on 2023-10-23 13:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('workshops', '0267_trainingrequest_accept_invalid_member_code'), + ] + + operations = [ + migrations.RemoveField( + model_name='workshoprequest', + name='member_affiliation', + ), + ] diff --git a/amy/workshops/models.py b/amy/workshops/models.py index a4becefb0..079356dd6 100644 --- a/amy/workshops/models.py +++ b/amy/workshops/models.py @@ -2895,21 +2895,6 @@ class CommonRequest(SecondaryEmailMixin, models.Model): verbose_name="Department/School/Library affiliation (if applicable)", ) - MEMBER_AFFILIATION_CHOICES = ( - ("yes", "Yes"), - ("no", "No"), - ("unsure", "I'm not sure"), - ) - member_affiliation = models.CharField( - max_length=STR_MED, - null=False, - default="no", - blank=True, - choices=MEMBER_AFFILIATION_CHOICES, - verbose_name="Are you affiliated with a Carpentries member organization?", - help_text="This may be the same as your institution above, " - "or another institution.", - ) member_code = models.CharField( max_length=STR_MED, blank=True,