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

Ticket/user reminder mail setting #5219

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 55 additions & 5 deletions bluebottle/activities/messages.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from pytz import timezone
from datetime import timedelta

from django.urls import reverse
from django.db.models import Sum, Q
from django.template.defaultfilters import time, date
from django.urls import reverse
from django.utils.timezone import get_current_timezone, now
from django.utils.translation import pgettext_lazy as pgettext
from pytz import timezone

from bluebottle.initiatives.models import InitiativePlatformSettings
from django.utils.timezone import get_current_timezone

from bluebottle.notifications.messages import TransitionMessage
from django.utils.translation import pgettext_lazy as pgettext
from bluebottle.utils.utils import get_current_host, get_current_language


Expand Down Expand Up @@ -445,3 +446,52 @@ def get_recipients(self):
return [self.obj.team.owner]
else:
return []


class BaseDoGoodHoursReminderNotification(TransitionMessage):

@property
def action_link(self):
return self.obj.get_absolute_url()

action_title = pgettext('email', 'Find activities')

def get_recipients(self):
"""members with do good hours"""
from bluebottle.members.models import Member
from bluebottle.members.models import MemberPlatformSettings

year = now().year
do_good_hours = timedelta(hours=MemberPlatformSettings.load().do_good_hours)

members = Member.objects.annotate(
hours=Sum(
'contributor__contributions__timecontribution__value',
filter=Q(contributor__contributions__start__year=year)
),
).filter(
Q(hours__lt=do_good_hours) | Q(hours__isnull=True),
is_active=True,
receive_reminder_emails=True
).distinct()
return members


class DoGoodHoursReminderQ1Notification(BaseDoGoodHoursReminderNotification):
subject = pgettext('email', "Are you ready to do good? Q1")
template = 'messages/do-good-hours/reminder-q1'


class DoGoodHoursReminderQ2Notification(BaseDoGoodHoursReminderNotification):
subject = pgettext('email', "Are you ready to do good? Q2")
template = 'messages/do-good-hours/reminder-q2'


class DoGoodHoursReminderQ3Notification(BaseDoGoodHoursReminderNotification):
subject = pgettext('email', "Are you ready to do good? Q3")
template = 'messages/do-good-hours/reminder-q3'


class DoGoodHoursReminderQ4Notification(BaseDoGoodHoursReminderNotification):
subject = pgettext('email', "Are you ready to do good? Q4")
template = 'messages/do-good-hours/reminder-q4'
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% extends "base.mail.html" %}
{% load i18n %}

{% block content %}
<p>
{% blocktrans context 'email' %}Hi {{ recipient_name }},{% endblocktrans %}
</p>
{% block message %}{% endblock %}
{% endblock %}

{% block action %}
<a href="{{ action_link }}" class="action-email">{{ action_title }}</a>
{% endblock %}`
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "mails/messages/do-good-hours/reminder-base.html" %}
{% load i18n %}

{% block message %}
{% blocktrans context 'email' %}
First reminder
{% endblocktrans %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "mails/messages/do-good-hours/reminder-base.html" %}
{% load i18n %}

{% block message %}
{% blocktrans context 'email' %}
Second reminder
{% endblocktrans %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "mails/messages/do-good-hours/reminder-base.html" %}
{% load i18n %}

{% block message %}
{% blocktrans context 'email' %}
Third reminder
{% endblocktrans %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "mails/messages/do-good-hours/reminder-base.html" %}
{% load i18n %}

{% block message %}
{% blocktrans context 'email' %}
Fourth reminder
{% endblocktrans %}
{% endblock %}
116 changes: 114 additions & 2 deletions bluebottle/activities/tests/test_notifications.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
from datetime import timedelta

from django.utils.timezone import now

from bluebottle.activities.messages import (
ActivityRejectedNotification, ActivityCancelledNotification,
ActivitySucceededNotification, ActivityRestoredNotification,
ActivityExpiredNotification, TeamAddedMessage,
TeamAppliedMessage, TeamCancelledMessage,
TeamCancelledTeamCaptainMessage, TeamWithdrawnActivityOwnerMessage,
TeamWithdrawnMessage, TeamMemberAddedMessage, TeamMemberWithdrewMessage,
TeamMemberRemovedMessage, TeamReappliedMessage, TeamCaptainAcceptedMessage
TeamMemberRemovedMessage, TeamReappliedMessage, TeamCaptainAcceptedMessage, DoGoodHoursReminderQ1Notification,
DoGoodHoursReminderQ3Notification, DoGoodHoursReminderQ2Notification, DoGoodHoursReminderQ4Notification
)
from bluebottle.activities.tests.factories import TeamFactory
from bluebottle.members.models import MemberPlatformSettings, Member
from bluebottle.notifications.models import NotificationPlatformSettings
from bluebottle.test.factory_models.accounts import BlueBottleUserFactory
from bluebottle.test.utils import NotificationTestCase
from bluebottle.time_based.tests.factories import (
DateActivityFactory, PeriodActivityFactory, PeriodParticipantFactory
DateActivityFactory, PeriodActivityFactory, PeriodParticipantFactory, DateActivitySlotFactory,
DateParticipantFactory, SlotParticipantFactory
)


Expand Down Expand Up @@ -260,3 +268,107 @@ def test_team_member_removed_notification(self):

self.assertActionLink(self.obj.activity.get_absolute_url())
self.assertActionTitle('View activity')


class DoGoodHoursReminderNotificationTestCase(NotificationTestCase):

def setUp(self):
self.obj = NotificationPlatformSettings.load()
self.obj = MemberPlatformSettings.load()
self.obj.do_good_hours = 8
self.obj.save()
activity = DateActivityFactory.create(
slots=[],
slot_selection='free',
)

slot1 = DateActivitySlotFactory.create(
start=now() - timedelta(days=2),
duration=timedelta(hours=4),
activity=activity
)
slot2 = DateActivitySlotFactory.create(
start=now() - timedelta(days=1),
duration=timedelta(hours=4),
activity=activity
)
old_slot = DateActivitySlotFactory.create(
start=now().replace(year=2011),
duration=timedelta(hours=8),
activity=activity
)

self.active_user = BlueBottleUserFactory.create(first_name='Active')
part1 = DateParticipantFactory.create(
user=self.active_user,
activity=activity
)
SlotParticipantFactory.create(
participant=part1,
slot=slot1
)
SlotParticipantFactory.create(
participant=part1,
slot=slot2
)
self.moderate_user = BlueBottleUserFactory.create(first_name='Moderate')
part2 = DateParticipantFactory.create(
user=self.moderate_user,
activity=activity
)
SlotParticipantFactory.create(
participant=part2,
slot=slot1
)
SlotParticipantFactory.create(
participant=part2,
slot=old_slot
)
self.passive_user = BlueBottleUserFactory.create(first_name='Passive')
part3 = DateParticipantFactory.create(
user=self.passive_user,
activity=activity
)

SlotParticipantFactory.create(
participant=part3,
slot=old_slot
)

Member.objects.exclude(id__in=[
self.active_user.id,
self.passive_user.id,
self.moderate_user.id,
]).update(receive_reminder_emails=False)

def test_reminder_q1(self):
self.message_class = DoGoodHoursReminderQ1Notification
self.create()
self.assertRecipients([self.moderate_user, self.passive_user])
self.assertSubject("Are you ready to do good? Q1")
self.assertBodyContains('First reminder')
self.assertActionTitle('Find activities')

def test_reminder_q2(self):
self.message_class = DoGoodHoursReminderQ2Notification
self.create()
self.assertRecipients([self.moderate_user, self.passive_user])
self.assertSubject("Are you ready to do good? Q2")
self.assertBodyContains('Second reminder')
self.assertActionTitle('Find activities')

def test_reminder_q3(self):
self.message_class = DoGoodHoursReminderQ3Notification
self.create()
self.assertRecipients([self.moderate_user, self.passive_user])
self.assertSubject("Are you ready to do good? Q3")
self.assertBodyContains('Third reminder')
self.assertActionTitle('Find activities')

def test_reminder_q4(self):
self.message_class = DoGoodHoursReminderQ4Notification
self.create()
self.assertRecipients([self.moderate_user, self.passive_user])
self.assertSubject("Are you ready to do good? Q4")
self.assertBodyContains('Fourth reminder')
self.assertActionTitle('Find activities')
14 changes: 11 additions & 3 deletions bluebottle/members/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,16 @@ class MemberPlatformSettingsAdmin(BasePlatformSettingsAdmin, NonSortableParentAd
}
),
(
_('Initiatives'),
_('Engagement'),
{
'fields': (
'create_initiatives',
)
'do_good_hours',
'reminder_q1',
'reminder_q2',
'reminder_q3',
'reminder_q4'
),
}
),
)
Expand Down Expand Up @@ -385,6 +390,8 @@ def get_fieldsets(self, request, obj=None):
{
'fields':
[
'hours_spent',
'hours_planned',
'initiatives',
'date_activities',
'period_activities',
Expand Down Expand Up @@ -439,7 +446,8 @@ def get_readonly_fields(self, request, obj=None):
'updated', 'deleted', 'login_as_link',
'reset_password', 'resend_welcome_link',
'initiatives', 'period_activities', 'date_activities',
'funding', 'deeds', 'collect', 'kyc'
'funding', 'deeds', 'collect', 'kyc',
'hours_spent', 'hours_planned'
]

user_groups = request.user.groups.all()
Expand Down
25 changes: 25 additions & 0 deletions bluebottle/members/migrations/0063_auto_20220818_0637.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 2.2.24 on 2022-08-18 04:37

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


class Migration(migrations.Migration):

dependencies = [
('members', '0062_auto_20220815_1751'),
]

operations = [
migrations.AddField(
model_name='memberplatformsettings',
name='do_good_hours',
field=models.IntegerField(
blank=True,
help_text='The amount of hours users can spend each year. '
'Leave empty if no restrictions apply.',
null=True
),
),
]
35 changes: 35 additions & 0 deletions bluebottle/members/migrations/0064_auto_20220825_0840.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generated by Django 2.2.24 on 2022-08-25 06:40

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


class Migration(migrations.Migration):

dependencies = [
('members', '0063_auto_20220818_0637'),
]

operations = [
migrations.AddField(
model_name='memberplatformsettings',
name='reminder_q1',
field=models.BooleanField(default=False, help_text='This activation mail is send on January 15th.'),
),
migrations.AddField(
model_name='memberplatformsettings',
name='reminder_q2',
field=models.BooleanField(default=False, help_text='This activation mail is send on April 15th.'),
),
migrations.AddField(
model_name='memberplatformsettings',
name='reminder_q3',
field=models.BooleanField(default=False, help_text='This activation mail is send on September 1st.'),
),
migrations.AddField(
model_name='memberplatformsettings',
name='reminder_q4',
field=models.BooleanField(default=False, help_text='This activation mail is send on October 15th.'),
),
]
18 changes: 18 additions & 0 deletions bluebottle/members/migrations/0065_auto_20220825_1055.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2022-08-25 08:55

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('members', '0064_auto_20220825_0840'),
]

operations = [
migrations.AddField(
model_name='member',
name='receive_reminder_emails',
field=models.BooleanField(default=True, help_text='User receives emails reminding them about their do good hours', verbose_name='Receive reminder emails'),
),
]
Loading