Display and allow updating bulletin subscriptions
This commit is contained in:
parent
62ebe96520
commit
bc2cb70aec
@ -31,6 +31,7 @@ def environment(**options):
|
|||||||
env.globals.update({
|
env.globals.update({
|
||||||
'import': importlib.import_module, # forgive me for I have sinned
|
'import': importlib.import_module, # forgive me for I have sinned
|
||||||
'localtime': lambda dt: timezone.localtime(dt).strftime('%Y-%m-%d %H:%M'),
|
'localtime': lambda dt: timezone.localtime(dt).strftime('%Y-%m-%d %H:%M'),
|
||||||
|
'settings': settings,
|
||||||
'static': staticfiles_storage.url,
|
'static': staticfiles_storage.url,
|
||||||
'url': reverse,
|
'url': reverse,
|
||||||
'MEDIA_URL': settings.MEDIA_URL,
|
'MEDIA_URL': settings.MEDIA_URL,
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
<a class="ui card" href="{{ url('membership') }}">
|
<a class="ui card" href="{{ url('membership') }}">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header">Membership Portal</div>
|
<div class="header">Membership Portal</div>
|
||||||
<div class="description">View and update your membership details.</div>
|
<div class="description">View and update your membership details. Update your bulletin subscription.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui bottom attached primary button">
|
<div class="ui bottom attached primary button">
|
||||||
<i class="chevron right icon" style="margin: 0 .42857143em 0 -.21428571em;"></i>
|
<i class="chevron right icon" style="margin: 0 .42857143em 0 -.21428571em;"></i>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<h1>Membership details</h1>
|
<h1>Membership details</h1>
|
||||||
|
|
||||||
<form class="ui form" method="POST" action="{{ url('membership') }}">
|
<form class="ui form" method="POST" action="{{ url('membership') }}">
|
||||||
<div class="ui required inline grid field">
|
<div class="ui disabled inline grid field">
|
||||||
<label class="three wide column">Member number</label>
|
<label class="three wide column">Member number</label>
|
||||||
<div class="nine wide column">{{ member.id }}</div>
|
<div class="nine wide column">{{ member.id }}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<label class="three wide column">Student ID</label>
|
<label class="three wide column">Student ID</label>
|
||||||
<input class="nine wide column" type="text" name="student_id" value="{{ member.student_id }}">
|
<input class="nine wide column" type="text" name="student_id" value="{{ member.student_id }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="ui required inline grid field">
|
<div class="ui disabled inline grid field">
|
||||||
<label class="three wide column">Student email</label>
|
<label class="three wide column">Student email</label>
|
||||||
<div class="nine wide column">{{ member.email }}</div>
|
<div class="nine wide column">{{ member.email }}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -71,10 +71,40 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<div class="ui required inline grid field">
|
<div class="ui disabled inline grid field">
|
||||||
<label class="three wide column">Membership expiry</label>
|
<label class="three wide column">Membership expiry</label>
|
||||||
<div class="nine wide column">{{ member.expires.strftime('%d %B %Y') }}</div>
|
<div class="nine wide column">{{ member.expires.strftime('%d %B %Y') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if 'sspromotions' in settings.INSTALLED_APPS %}
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<h2>Bulletin subscriptions</h2>
|
||||||
|
|
||||||
|
<div class="ui required inline grid field">
|
||||||
|
<label class="three wide column">Opt-in/out</label>
|
||||||
|
<select id="drop_bulletin_subscribe" class="ui dropdown eleven wide column" name="bulletin_subscribe">
|
||||||
|
<option value="">Bulletin opt-in/out</option>
|
||||||
|
<option value="0">Do not email me the MUMUS Bulletin</option>
|
||||||
|
<option value="1">Email me the weekly MUMUS Bulletin</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="ui inline grid field">
|
||||||
|
<label class="three wide column">Subscriptions</label>
|
||||||
|
<div class="eleven wide column">
|
||||||
|
{% for group in import('sspromotions.models').Group.objects.all() %}
|
||||||
|
{% if group.contains_member(member) or group.subscribable %}
|
||||||
|
<div class="{% if not group.subscribable %}disabled {% endif %}field" style="display: inline; margin-right: 1em;">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="bulletin_group_{{ group.id }}" id="bulletin_group_{{ group.id }}"{% if group.contains_member(member) %} checked{% endif %}>
|
||||||
|
<label for="bulletin_group_{{ group.id }}">{{ group.name }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
{% if errors %}
|
{% if errors %}
|
||||||
<div class="ui visible error message"><ul>
|
<div class="ui visible error message"><ul>
|
||||||
@ -96,6 +126,9 @@
|
|||||||
$('.ui.dropdown').dropdown();
|
$('.ui.dropdown').dropdown();
|
||||||
$('#drop_year').dropdown('set selected', '{{ member.year }}');
|
$('#drop_year').dropdown('set selected', '{{ member.year }}');
|
||||||
$('#drop_msa').dropdown('set selected', '{{ '1' if member.is_msa else '0' }}');
|
$('#drop_msa').dropdown('set selected', '{{ '1' if member.is_msa else '0' }}');
|
||||||
|
{% if 'sspromotions' in settings.INSTALLED_APPS %}
|
||||||
|
$('#drop_bulletin_subscribe').dropdown('set selected', '{{ '1' if import('sspromotions.models').BulletinSubscription.is_member_subscribed(member) else '0' }}');
|
||||||
|
{% endif %}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -52,6 +52,15 @@ def index(request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
member.save()
|
member.save()
|
||||||
return render(request, 'ssmembership/index.html', {'member': member, 'years': models.Member.YEARS})
|
|
||||||
|
|
||||||
return render(request, 'ssmembership/index.html', {'member': member})
|
# Update bulletin
|
||||||
|
if 'sspromotions' in settings.INSTALLED_APPS:
|
||||||
|
import sspromotions.models
|
||||||
|
sspromotions.models.BulletinSubscription.set_member_subscribed(member, True if request.POST['bulletin_subscribe'] == '1' else False)
|
||||||
|
for group in sspromotions.models.Group.objects.filter(subscribable=True).all():
|
||||||
|
if ('bulletin_group_' + str(group.id)) in request.POST and request.POST['bulletin_group_' + str(group.id)]:
|
||||||
|
group.subscribe_member(member, True)
|
||||||
|
else:
|
||||||
|
group.subscribe_member(member, False)
|
||||||
|
|
||||||
|
return render(request, 'ssmembership/index.html', {'member': member, 'years': models.Member.YEARS})
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from ssmembership.models import Member
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -27,6 +29,9 @@ class Group(models.Model):
|
|||||||
|
|
||||||
managers = JSONField(default=[], blank=True)
|
managers = JSONField(default=[], blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['order', 'id']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
@ -41,8 +46,40 @@ class Group(models.Model):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class Meta:
|
def contains_member(self, member):
|
||||||
ordering = ['order', 'id']
|
if self.subscribable:
|
||||||
|
return GroupSubscription.objects.filter(member=member, group=self).count() > 0
|
||||||
|
|
||||||
|
if self.name == 'All Years':
|
||||||
|
return True
|
||||||
|
if next(v for k, v in Member.YEARS if k == member.year) in self.name.split('/'):
|
||||||
|
# Year level group
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def subscribe_member(self, member, subscribe):
|
||||||
|
if not self.subscribable:
|
||||||
|
raise Exception('Cannot subscribe to an unsubscribable group')
|
||||||
|
|
||||||
|
if subscribe:
|
||||||
|
if GroupSubscription.objects.filter(member=member, group=self).count() == 0:
|
||||||
|
subscription = GroupSubscription(member=member, group=self)
|
||||||
|
subscription.save()
|
||||||
|
else:
|
||||||
|
GroupSubscription.objects.filter(member=member, group=self).delete()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_member_groups(member):
|
||||||
|
# Subscribable groups
|
||||||
|
subscriptions = GroupSubscription.objects.filter(member=member)
|
||||||
|
groups = set(subscription.group for subscription in subscriptions.all())
|
||||||
|
|
||||||
|
# Non-subscribable groups
|
||||||
|
for group in Group.objects.filter(subscribable=False):
|
||||||
|
if group.contains_member(member):
|
||||||
|
groups.add(group)
|
||||||
|
|
||||||
|
return groups
|
||||||
|
|
||||||
class BulletinItem(models.Model):
|
class BulletinItem(models.Model):
|
||||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
@ -62,3 +99,24 @@ class BulletinItem(models.Model):
|
|||||||
if user.email in self.author.delegates:
|
if user.email in self.author.delegates:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class BulletinSubscription(models.Model):
|
||||||
|
member = models.ForeignKey(Member, on_delete=models.CASCADE)
|
||||||
|
subscribed = models.BooleanField()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_member_subscribed(member):
|
||||||
|
return BulletinSubscription.objects.filter(member=member, subscribed=True).count() > 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_member_subscribed(member, subscribed):
|
||||||
|
if BulletinSubscription.objects.filter(member=member).count() > 0:
|
||||||
|
subscription = BulletinSubscription.objects.get(member=member)
|
||||||
|
else:
|
||||||
|
subscription = BulletinSubscription(member=member)
|
||||||
|
subscription.subscribed = subscribed
|
||||||
|
subscription.save()
|
||||||
|
|
||||||
|
class GroupSubscription(models.Model):
|
||||||
|
member = models.ForeignKey(Member, on_delete=models.CASCADE)
|
||||||
|
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||||
|
Loading…
Reference in New Issue
Block a user