Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Emails] New self organised workshop #2654

Merged
merged 8 commits into from
Jun 3, 2024
47 changes: 47 additions & 0 deletions amy/api/v2/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework import serializers

from emails.models import MAX_LENGTH, ScheduledEmail
from extrequests.models import SelfOrganisedSubmission
from recruitment.models import InstructorRecruitmentSignup
from workshops.models import (
Award,
Expand Down Expand Up @@ -308,3 +309,49 @@ class Meta:
"event_required",
"involvement_required",
)


class SelfOrganisedSubmissionSerializer(serializers.ModelSerializer):
event = serializers.SlugRelatedField(read_only=True, slug_field="slug")
additional_contact = serializers.CharField()
country = serializers.CharField()
workshop_types = serializers.SlugRelatedField(
many=True, read_only=True, slug_field="name"
)

class Meta:
model = SelfOrganisedSubmission
fields = (
"pk",
"assigned_to",
"state",
"created_at",
"last_updated_at",
"data_privacy_agreement",
"code_of_conduct_agreement",
"host_responsibilities",
"event",
"personal",
"family",
"email",
"institution",
"institution_other_name",
"institution_other_URL",
"institution_department",
"member_code",
"online_inperson",
"workshop_listed",
"public_event",
"public_event_other",
"additional_contact",
"start",
"end",
"workshop_url",
"workshop_format",
"workshop_format_other",
"workshop_types",
"workshop_types_other",
"workshop_types_other_explain",
"country",
"language",
)
1 change: 1 addition & 0 deletions amy/api/v2/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
router.register("scheduledemail", views.ScheduledEmailViewSet)
router.register("trainingprogress", views.TrainingProgressViewSet)
router.register("trainingrequirement", views.TrainingRequirementViewSet)
router.register("selforganisedsubmission", views.SelfOrganisedSubmissionViewSet)


urlpatterns = [
Expand Down
17 changes: 17 additions & 0 deletions amy/api/v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
PersonSerializer,
ScheduledEmailLogDetailsSerializer,
ScheduledEmailSerializer,
SelfOrganisedSubmissionSerializer,
TrainingProgressSerializer,
TrainingRequirementSerializer,
)
from emails.controller import EmailController
from emails.models import ScheduledEmail, ScheduledEmailStatus
from extrequests.models import SelfOrganisedSubmission
from recruitment.models import InstructorRecruitmentSignup
from workshops.models import (
Award,
Expand Down Expand Up @@ -251,3 +253,18 @@ class TrainingRequirementViewSet(viewsets.ReadOnlyModelViewSet):
queryset = TrainingRequirement.objects.order_by("pk").all()
serializer_class = TrainingRequirementSerializer
pagination_class = StandardResultsSetPagination


class SelfOrganisedSubmissionViewSet(viewsets.ReadOnlyModelViewSet):
authentication_classes = (
TokenAuthentication,
SessionAuthentication,
)
permission_classes = (
IsAuthenticated,
ApiAccessPermission,
)

queryset = SelfOrganisedSubmission.objects.order_by("pk").all()
serializer_class = SelfOrganisedSubmissionSerializer
pagination_class = StandardResultsSetPagination
3 changes: 3 additions & 0 deletions amy/emails/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
new_membership_onboarding_receiver,
new_membership_onboarding_update_receiver,
)
from emails.actions.new_self_organised_workshop import (
new_self_organised_workshop_receiver,
)
from emails.actions.persons_merged import persons_merged_receiver
from emails.actions.post_workshop_7days import (
post_workshop_7days_cancel_receiver,
Expand Down
4 changes: 2 additions & 2 deletions amy/emails/actions/admin_signs_instructor_up_for_workshop.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
},
], # type: ignore
}, # type: ignore
],
)


Expand Down
22 changes: 15 additions & 7 deletions amy/emails/actions/host_instructors_introduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
HostInstructorsIntroductionKwargs,
StrategyEnum,
)
from emails.utils import api_model_url, immediate_action, scalar_value_none
from emails.utils import (
api_model_url,
immediate_action,
log_condition_elements,
scalar_value_none,
)
from recruitment.models import InstructorRecruitment
from workshops.models import Event, Task

Expand All @@ -41,17 +46,20 @@ def host_instructors_introduction_strategy(event: Event) -> StrategyEnum:
start_date_in_at_least_7days = event.start and event.start >= (
timezone.now().date() + timedelta(days=7)
)
logger.debug(
f"{no_open_recruitment=}, {not_self_organised=}, "
f"{start_date_in_at_least_7days=}"
)

active = not event.tags.filter(name__in=["cancelled", "unresponsive", "stalled"])
host = Task.objects.filter(role__name="host", event=event).first()
at_least_2_instructors = (
Task.objects.filter(role__name="instructor", event=event).count() >= 2
)
logger.debug(f"{active=}, {host=}, {at_least_2_instructors=}")

log_condition_elements(
not_self_organised=not_self_organised,
no_open_recruitment=no_open_recruitment,
start_date_in_at_least_7days=start_date_in_at_least_7days,
active=active,
host=host,
at_least_2_instructors=at_least_2_instructors,
)

email_should_exist = (
not_self_organised
Expand Down
4 changes: 2 additions & 2 deletions amy/emails/actions/instructor_badge_awarded.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
},
], # type: ignore
}, # type: ignore
],
)


Expand Down
4 changes: 2 additions & 2 deletions amy/emails/actions/instructor_confirmed_for_workshop.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
},
], # type: ignore
}, # type: ignore
],
)


Expand Down
4 changes: 2 additions & 2 deletions amy/emails/actions/instructor_declined_from_workshop.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
},
], # type: ignore
}, # type: ignore
],
)


Expand Down
4 changes: 2 additions & 2 deletions amy/emails/actions/instructor_signs_up_for_workshop.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
},
], # type: ignore
}, # type: ignore
],
)


Expand Down
9 changes: 7 additions & 2 deletions amy/emails/actions/instructor_training_approaching.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
InstructorTrainingApproachingKwargs,
StrategyEnum,
)
from emails.utils import api_model_url, one_month_before
from emails.utils import api_model_url, log_condition_elements, one_month_before
from workshops.models import Event, Task

logger = logging.getLogger("amy")
Expand All @@ -36,7 +36,12 @@ def instructor_training_approaching_strategy(event: Event) -> StrategyEnum:
Task.objects.filter(event=event, role__name="instructor").count() >= 2
)
start_date_in_future = event.start and event.start >= timezone.now().date()
logger.debug(f"{has_TTT=}, {has_at_least_2_instructors=}, {start_date_in_future=}")

log_condition_elements(
has_TTT=has_TTT,
has_at_least_2_instructors=has_at_least_2_instructors,
start_date_in_future=start_date_in_future,
)

email_should_exist = has_TTT and has_at_least_2_instructors and start_date_in_future
logger.debug(f"{email_should_exist=}")
Expand Down
18 changes: 15 additions & 3 deletions amy/emails/actions/instructor_training_completed_not_badged.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
InstructorTrainingCompletedNotBadgedKwargs,
StrategyEnum,
)
from emails.utils import api_model_url, scalar_value_url, two_months_after
from emails.utils import (
api_model_url,
log_condition_elements,
scalar_value_url,
two_months_after,
)
from workshops.models import Person, TrainingProgress, TrainingRequirement

logger = logging.getLogger("amy")
Expand Down Expand Up @@ -82,6 +87,13 @@ def instructor_training_completed_not_badged_strategy(person: Person) -> Strateg
],
).exists()

log_condition_elements(
**{
"person_annotated.passed_training": person_annotated.passed_training,
"all_requirements_passed": all_requirements_passed,
}
)

email_should_exist = (
bool(person_annotated.passed_training) and not all_requirements_passed
)
Expand Down Expand Up @@ -227,8 +239,8 @@ def get_recipients_context_json(
{
"api_uri": api_model_url("person", context["person"].pk),
"property": "email",
}
], # type: ignore
} # type: ignore
],
)


Expand Down
24 changes: 20 additions & 4 deletions amy/emails/actions/new_membership_onboarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
NewMembershipOnboardingKwargs,
StrategyEnum,
)
from emails.utils import api_model_url, immediate_action, one_month_before
from emails.utils import (
api_model_url,
immediate_action,
log_condition_elements,
one_month_before,
)
from fiscal.models import MembershipTask
from workshops.models import Membership

Expand All @@ -40,15 +45,26 @@ def new_membership_onboarding_strategy(membership: Membership) -> StrategyEnum:
template__signal=NEW_MEMBERSHIP_ONBOARDING_SIGNAL_NAME,
state=ScheduledEmailStatus.SCHEDULED,
).exists()
task_count = MembershipTask.objects.filter(
membership=membership, role__name__in=MEMBERSHIP_TASK_ROLES_EXPECTED
).count()

log_condition_elements(
**{
"membership.pk": membership.pk,
"membership.rolled_from_membership": getattr(
membership, "rolled_from_membership", None
),
"task_count": task_count,
}
)

# Membership can't be removed without removing the tasks first. This is when the
# email would be de-scheduled.
email_should_exist = (
membership.pk
and getattr(membership, "rolled_from_membership", None) is None
and MembershipTask.objects.filter(
membership=membership, role__name__in=MEMBERSHIP_TASK_ROLES_EXPECTED
).count()
and task_count
)

if not email_scheduled and email_should_exist:
Expand Down
Loading
Loading