Implement sending urgent reminder emails to all members of the applicable committee for an endorsed budget

This commit is contained in:
Yingtong Li 2023-05-01 19:26:18 +10:00
parent 490faa8147
commit 8a3a09d8ab
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
3 changed files with 91 additions and 67 deletions

View File

@ -259,10 +259,15 @@
{% if revision.state == import('sstreasury.models').BudgetState.ENDORSED.value %} {% if revision.state == import('sstreasury.models').BudgetState.ENDORSED.value %}
<h2>Committee voting</h2> <h2>Committee voting</h2>
<p>{{ dict(settings.AVAILABLE_APPROVERS)[revision.approver][1] }} votes in favour are required for approval.</p> <form action="{{ url('budget_action', kwargs={'id': revision.budget.id}) }}" method="POST">
<p>
{{ dict(settings.AVAILABLE_APPROVERS)[revision.approver][1] }} votes in favour are required for approval.
{% if is_latest and request.user.groups.filter(name='Executive').exists() %}
<button style="margin-left: 1em;" class="ui small primary labeled icon button" type="submit" name="action" value="SendVotingReminders"><i class="envelope icon"></i>Send urgent reminder emails</button>
{% endif %}
</p>
<form class="ui three column grid" action="{{ url('budget_action', kwargs={'id': revision.budget.id}) }}" method="POST"> <div class="ui three column grid">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<div class="column"> <div class="column">
<div class="ui fluid card"> <div class="ui fluid card">
<div class="content"> <div class="content">
@ -326,6 +331,8 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div>
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
</form> </form>
{% endif %} {% endif %}

View File

@ -0,0 +1,3 @@
This is an urgent reminder from {{ requester.first_name }} {{ requester.last_name }} to vote on a budget titled *{{ revision.name }}* (BU-{{ revision.budget.id }}), which has been endorsed by Treasury and is awaiting committee review.
{{ baseurl }}{{ url('budget_view', kwargs={'id': revision.budget.id}) }}

View File

@ -477,6 +477,20 @@ def budget_action(request, budget, revision):
with transaction.atomic(): with transaction.atomic():
revision.update_state(request.user, models.BudgetState.CANCELLED) revision.update_state(request.user, models.BudgetState.CANCELLED)
if 'SendVotingReminders' in actions:
if revision.state != models.BudgetState.ENDORSED.value:
raise PermissionDenied
if not request.user.groups.filter(name='Executive').exists():
# TODO: Make this group configurable
raise PermissionDenied
# Send emails
emailer = Emailer()
for user in User.objects.filter(groups__name=revision.approver):
# Email only if not voted yet
if not revision.budgetvote_set.filter(voter=user).exists():
emailer.send_mail([user.email], 'URGENT action required: {} (BU-{})'.format(revision.name, budget.id), 'sstreasury/email/budget_vote_reminder.md', {'revision': revision, 'requester': request.user})
if 'VoteInFavour' in actions or 'VoteAgainst' in actions or 'VoteAbstain' in actions: if 'VoteInFavour' in actions or 'VoteAgainst' in actions or 'VoteAbstain' in actions:
if not revision.can_vote(request.user): if not revision.can_vote(request.user):
raise PermissionDenied raise PermissionDenied
@ -489,7 +503,7 @@ def budget_action(request, budget, revision):
vote_type = models.BudgetVoteType.ABSTAIN vote_type = models.BudgetVoteType.ABSTAIN
# Already exists? # Already exists?
if revision.budgetvote_set.filter(is_current=True, voter=request.user, vote_type=vote_type.value): if revision.budgetvote_set.filter(is_current=True, voter=request.user, vote_type=vote_type.value).exists():
# No need to create new vote # No need to create new vote
pass pass
else: else: