Skip to content

Commit

Permalink
feat(programme,mailings): manage programme recipient groups
Browse files Browse the repository at this point in the history
  • Loading branch information
japsu committed Apr 15, 2023
1 parent 955d218 commit e83656f
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 43 deletions.
7 changes: 7 additions & 0 deletions core/models/event_meta_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def get_group(self, suffix):

return Group.objects.get(name=group_name)

def get_group_if_exists(self, suffix):
from django.contrib.auth.models import Group

group_name = self.make_group_name(self.event, suffix)

return Group.objects.filter(name=group_name).first()

def is_user_admin(self, user):
"""
Bridge between legacy access control and CBAC. Users that can do anything in an event are considered
Expand Down
3 changes: 0 additions & 3 deletions labour/models/signup.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,6 @@ def apply_state_email_aliases(self):
GroupEmailAliasGrant.ensure_aliases(self.person)

def apply_state_send_messages(self, resend=False):
if "mailings" not in settings.INSTALLED_APPS:
return

from mailings.models import Message

Message.send_messages(self.event, "labour", self.person)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.1.7 on 2023-04-15 07:36

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("programme", "0117_programme_tracon2023_accessibility_warnings_and_more"),
("mailings", "0008_auto_20161026_2343"),
]

operations = [
migrations.AddField(
model_name="recipientgroup",
name="programme_category",
field=models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="programme.category"
),
),
migrations.AlterField(
model_name="recipientgroup",
name="app_label",
field=models.CharField(
choices=[("labour", "Työvoima"), ("programme", "Ohjelma")], max_length=63, verbose_name="Sovellus"
),
),
]
14 changes: 6 additions & 8 deletions mailings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class RecipientGroup(models.Model):
group = models.ForeignKey("auth.Group", on_delete=models.CASCADE, verbose_name="Käyttäjäryhmä")
verbose_name = models.CharField(max_length=63, verbose_name="Nimi", blank=True, default="")
job_category = models.ForeignKey(JobCategory, on_delete=models.CASCADE, null=True, blank=True)
programme_category = models.ForeignKey("programme.Category", on_delete=models.CASCADE, null=True, blank=True)
personnel_class = models.ForeignKey(PersonnelClass, on_delete=models.CASCADE, null=True, blank=True)

def __str__(self):
Expand All @@ -41,6 +42,8 @@ def __str__(self):
kind = f" (tehtäväalue, {num_ppl} hlö)"
elif self.personnel_class:
kind = f" (henkilöstöluokka, {num_ppl} hlö)"
elif self.programme_category:
kind = f" (ohjelmaluokka, {num_ppl} hlö)"
else:
kind = f" ({num_ppl} hlö)"

Expand Down Expand Up @@ -120,18 +123,13 @@ def is_expired(self):
return self.expired_at is not None

def send(self, recipients=None, resend=False):
from .tasks import message_send

if not self.sent_at:
self.sent_at = timezone.now()
self.save()

if "background_tasks" in settings.INSTALLED_APPS:
from mailings.tasks import message_send

message_send.delay(
self.pk, [person.pk for person in recipients] if recipients is not None else None, resend
)
else:
self._send(recipients, resend)
message_send.delay(self.pk, [person.pk for person in recipients] if recipients is not None else None, resend)

def _send(self, recipients, resend):
from django.contrib.auth.models import User
Expand Down
45 changes: 45 additions & 0 deletions programme/migrations/0118_alter_programme_photography_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 4.1.7 on 2023-04-15 07:36

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("tracon2023", "0002_accessibilitywarning_timeslot"),
("programme", "0117_programme_tracon2023_accessibility_warnings_and_more"),
]

operations = [
migrations.AlterField(
model_name="programme",
name="photography",
field=models.CharField(
blank=True,
choices=[
("please", "Please photograph my programme"),
("okay", "It's OK to photograph my programme"),
("nope", "Please do not photograph my programme"),
],
help_text="Our official photographers will try to cover all programmes whose hosts request their programmes to be photographed.",
max_length=6,
verbose_name="Photography of your prorgamme",
),
),
migrations.AlterField(
model_name="programme",
name="tracon2023_accessibility_warnings",
field=models.ManyToManyField(
blank=True, to="tracon2023.accessibilitywarning", verbose_name="Accessibility warnings"
),
),
migrations.AlterField(
model_name="programme",
name="tracon2023_content_warnings",
field=models.TextField(
blank=True,
default="",
help_text="We will print content warnings in the programme schedule in order to give our visitors the requisite information to make educated choices about programme. If your programme contains bright lights, loud noises, smoke or similar effects, please choose them above. Please include any other content warnings in the text field.",
verbose_name="Content warnings",
),
),
]
50 changes: 31 additions & 19 deletions programme/models/programme.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@
("none", _("Not at all")),
]

PROGRAMME_STATES_ACTIVE = ["idea", "asked", "offered", "accepted", "published"]
PROGRAMME_STATES_NEW = ["idea", "asked", "offered"]
PROGRAMME_STATES_LIVE = ["accepted", "published"]
PROGRAMME_STATES_ACTIVE = PROGRAMME_STATES_NEW + PROGRAMME_STATES_LIVE
PROGRAMME_STATES_INACTIVE = ["rejected", "cancelled"]

LANGUAGE_CHOICES = [
Expand Down Expand Up @@ -1569,6 +1570,7 @@ def apply_state_async(self):

def _apply_state_async(self):
self.apply_state_group_membership()
self.apply_state_send_messages()

def apply_state_update_programme_roles(self):
self.programme_roles.update(is_active=self.is_active)
Expand All @@ -1582,30 +1584,40 @@ def apply_state_group_membership(self):
from core.utils import ensure_user_group_membership
from .programme_role import ProgrammeRole

try:
group = self.event.programme_event_meta.get_group("hosts")
except Group.DoesNotExist:
logger.warning("Event %s missing the programme hosts group", self.event)
return

for person in self.organizers.all():
assert person.user

if ProgrammeRole.objects.filter(
programme__category__event=self.event,
programme__state__in=PROGRAMME_STATES_ACTIVE,
person=person,
).exists():
# active programmist
groups_to_add = [group]
groups_to_remove = []
else:
# inactive programmist
groups_to_add = []
groups_to_remove = [group]
groups_to_add = []
groups_to_remove = []

for group, states in [
(self.event.programme_event_meta.get_group_if_exists("new"), PROGRAMME_STATES_NEW),
(self.event.programme_event_meta.get_group_if_exists("hosts"), PROGRAMME_STATES_ACTIVE),
(self.event.programme_event_meta.get_group_if_exists("live"), PROGRAMME_STATES_LIVE),
(self.event.programme_event_meta.get_group_if_exists("inactive"), PROGRAMME_STATES_INACTIVE),
]:
if not group:
continue

if ProgrammeRole.objects.filter(
programme__category__event=self.event,
programme__state__in=states,
person=person,
).exists():
# active programmist
groups_to_add.append(group)
else:
# inactive programmist
groups_to_remove.append(group)

ensure_user_group_membership(person.user, groups_to_add=groups_to_add, groups_to_remove=groups_to_remove)

def apply_state_send_messages(self, resend=False):
from mailings.models import Message

for person in self.organizers.all():
Message.send_messages(self.event, "programme", person)

def apply_state_create_badges(self, deleted_programme_roles=[]):
if "badges" not in settings.INSTALLED_APPS:
return
Expand Down
35 changes: 22 additions & 13 deletions programme/models/programme_event_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,38 +96,47 @@ def get_or_create_dummy(cls):
),
)

def create_groups(self):
from .category import Category

subjects: list[str | Category] = ["new", "hosts", "live", "rejected"]

for category in Category.objects.filter(event=self.event):
subjects.append(category)

return subjects

@classmethod
def get_or_create_groups(cls, event, subjects):
from mailings.models import RecipientGroup
from .category import Category

suffixes = [jc_or_suffix if isinstance(jc_or_suffix, str) else jc_or_suffix.slug for jc_or_suffix in subjects]
suffixes = [subject if isinstance(subject, str) else subject.slug for subject in subjects]

groups = super().get_or_create_groups(event, suffixes)

for subject, group in zip(subjects, groups):
# if isinstance(jc_or_suffix, JobCategory):
# verbose_name = jc_or_suffix.name
# job_category = jc_or_suffix
# personnel_class = None
if isinstance(subject, Category):
verbose_name = subject.title
category = subject
# elif isinstance(jc_or_suffix, PersonnelClass):
# verbose_name = jc_or_suffix.name
# job_category = None
# personnel_class = jc_or_suffix
# else:
if subject not in GROUP_VERBOSE_NAMES_BY_SUFFIX:
continue
else:
if subject not in GROUP_VERBOSE_NAMES_BY_SUFFIX:
continue

verbose_name = GROUP_VERBOSE_NAMES_BY_SUFFIX[subject]
job_category = None
personnel_class = None
verbose_name = GROUP_VERBOSE_NAMES_BY_SUFFIX[subject]
category = None
personnel_class = None

RecipientGroup.objects.get_or_create(
event=event,
app_label="programme",
group=group,
defaults=dict(
job_category=job_category,
personnel_class=personnel_class,
programme_category=category,
verbose_name=verbose_name,
),
)
Expand Down

0 comments on commit e83656f

Please sign in to comment.