diff --git a/sstreasury/jinja2/sstreasury/budget_view.html b/sstreasury/jinja2/sstreasury/budget_view.html
index deb9106..16e9ec0 100644
--- a/sstreasury/jinja2/sstreasury/budget_view.html
+++ b/sstreasury/jinja2/sstreasury/budget_view.html
@@ -29,12 +29,20 @@
{% if revision.state == import('sstreasury.models').BudgetState.DRAFT.value or revision.state == import('sstreasury.models').BudgetState.RESUBMIT.value %}
+
+ {% if request.user.groups.filter(name='Secretary').exists() %}
+
+
+
+ {% endif %}
{% elif revision.state == import('sstreasury.models').BudgetState.AWAIT_REVIEW.value and request.user.groups.filter(name='Treasury').exists() %}
- {% elif revision.state == import('sstreasury.models').BudgetState.ENDORSED.value and request.user.groups.filter(name='Secretary').exists() %}
- {# TODO #}
+ {% elif revision.state != import('sstreasury.models').BudgetState.APPROVED.value and request.user.groups.filter(name='Secretary').exists() %}
+
+
+
{% elif revision.state == import('sstreasury.models').BudgetState.APPROVED.value %}
{# Blank #}
{% else %}
@@ -43,6 +51,8 @@
{% if revision.state == import('sstreasury.models').BudgetState.DRAFT.value or revision.state == import('sstreasury.models').BudgetState.RESUBMIT.value or (revision.state != import('sstreasury.models').BudgetState.APPROVED.value and (request.user.groups.filter(name='Treasury').exists() or request.user.groups.filter(name='Secretary').exists())) %}
Edit
+ {% elif revision.state == import('sstreasury.models').BudgetState.APPROVED.value %}
+ {# Blank #}
{% else %}
This budget has been submitted and is now awaiting approval. If you wish to edit this budget, you must first withdraw it. This will revert the budget to a draft.
@@ -143,9 +153,13 @@
{% if revision.state == import('sstreasury.models').BudgetState.AWAIT_REVIEW.value and request.user.groups.filter(name='Treasury').exists() %}
-
+
-
+
+ {% elif revision.state != import('sstreasury.models').BudgetState.APPROVED.value and request.user.groups.filter(name='Secretary').exists() %}
+
+
+
{% endif %}
diff --git a/sstreasury/jinja2/sstreasury/email/approved.md b/sstreasury/jinja2/sstreasury/email/approved.md
new file mode 100644
index 0000000..3a07900
--- /dev/null
+++ b/sstreasury/jinja2/sstreasury/email/approved.md
@@ -0,0 +1,3 @@
+Your budget titled *{{ revision.name }}* has been reviewed by the committee and **approved**. The expenditure shown in the budget may now commence.
+
+{{ baseurl }}{{ url('budget_view', kwargs={'id': revision.budget.id}) }}
diff --git a/sstreasury/jinja2/sstreasury/email/endorsed_secretary.md b/sstreasury/jinja2/sstreasury/email/endorsed_secretary.md
new file mode 100644
index 0000000..47c08fd
--- /dev/null
+++ b/sstreasury/jinja2/sstreasury/email/endorsed_secretary.md
@@ -0,0 +1,3 @@
+A budget titled *{{ revision.name }}* has been endorsed by Treasury and referred to the committee for consideration at its next meeting.
+
+{{ baseurl }}{{ url('budget_view', kwargs={'id': revision.budget.id}) }}
diff --git a/sstreasury/jinja2/sstreasury/email/returned_committee.md b/sstreasury/jinja2/sstreasury/email/returned_committee.md
new file mode 100644
index 0000000..22866b0
--- /dev/null
+++ b/sstreasury/jinja2/sstreasury/email/returned_committee.md
@@ -0,0 +1,3 @@
+Your budget titled *{{ revision.name }}* has been reviewed by the committee and returned to you for re-drafting. You should make any requested changes and resubmit the budget.
+
+{{ baseurl }}{{ url('budget_view', kwargs={'id': revision.budget.id}) }}
diff --git a/sstreasury/views.py b/sstreasury/views.py
index 0b06ed4..c0153cc 100644
--- a/sstreasury/views.py
+++ b/sstreasury/views.py
@@ -46,23 +46,29 @@ def budget_list(request):
revision = budget.budgetrevision_set.reverse()[0]
state = models.BudgetState(revision.state)
- if request.user.groups.filter(name='Treasury').exists():
- if state == models.BudgetState.AWAIT_REVIEW:
- budgets_action.append(revision)
- elif state != models.BudgetState.APPROVED:
- budgets_open.append(revision)
- else:
- budgets_closed.append(revision)
+ group = None
+
+ if request.user.groups.filter(name='Treasury').exists() and state == models.BudgetState.AWAIT_REVIEW:
+ group = budgets_action
+ elif request.user.groups.filter(name='Secretary').exists() and state == models.BudgetState.ENDORSED:
+ group = budgets_action
else:
- if request.user not in revision.contributors.all():
- continue
-
- if state in [models.BudgetState.DRAFT, models.BudgetState.RESUBMIT]:
- budgets_action.append(revision)
- elif state in [models.BudgetState.AWAIT_REVIEW, models.BudgetState.ENDORSED]:
- budgets_open.append(revision)
+ if request.user in revision.contributors.all():
+ if state in [models.BudgetState.DRAFT, models.BudgetState.RESUBMIT]:
+ group = budgets_action
+ elif state in [models.BudgetState.AWAIT_REVIEW, models.BudgetState.ENDORSED]:
+ group = budgets_open
+ else:
+ group = budgets_closed
else:
- budgets_closed.append(revision)
+ if request.user in revision.contributors.all() or request.user.groups.filter(name='Treasury').exists() or request.user.groups.filter(name='Secretary').exists():
+ if state == models.BudgetState.APPROVED:
+ group = budgets_closed
+ else:
+ group = budgets_open
+
+ if group is not None:
+ group.append(revision)
return render(request, 'sstreasury/budget_list.html', {
'budgets_action': budgets_action,
@@ -272,6 +278,8 @@ def budget_action(request, budget, revision):
revision.save()
emailer = Emailer()
+ for user in User.objects.filter(groups__name='Secretary'):
+ emailer.send_mail([user.email], 'Action required: Budget endorsed: {}'.format(revision.name), 'sstreasury/email/endorsed_secretary.md', {'revision': revision})
for user in revision.contributors.all():
emailer.send_mail([user.email], 'Budget endorsed, awaiting committee approval: {}'.format(revision.name), 'sstreasury/email/endorsed.md', {'revision': revision})
@@ -293,4 +301,40 @@ def budget_action(request, budget, revision):
for user in revision.contributors.all():
emailer.send_mail([user.email], 'Action required: Budget returned for re-drafting: {}'.format(revision.name), 'sstreasury/email/returned.md', {'revision': revision})
+ if 'Approve' in actions:
+ if revision.state == models.BudgetState.APPROVED.value:
+ raise PermissionDenied
+ if not request.user.groups.filter(name='Secretary').exists():
+ raise PermissionDenied
+
+ with transaction.atomic():
+ revision.copy()
+ revision.author = request.user
+ revision.time = timezone.now()
+ revision.state = models.BudgetState.APPROVED.value
+ revision.action = models.BudgetAction.UPDATE_STATE.value
+ revision.save()
+
+ emailer = Emailer()
+ for user in revision.contributors.all():
+ emailer.send_mail([user.email], 'Budget approved: {}'.format(revision.name), 'sstreasury/email/approved.md', {'revision': revision})
+
+ if 'CmteReturn' in actions:
+ if revision.state == models.BudgetState.APPROVED.value:
+ raise PermissionDenied
+ if not request.user.groups.filter(name='Secretary').exists():
+ raise PermissionDenied
+
+ with transaction.atomic():
+ revision.copy()
+ revision.author = request.user
+ revision.time = timezone.now()
+ revision.state = models.BudgetState.RESUBMIT.value
+ revision.action = models.BudgetAction.UPDATE_STATE.value
+ revision.save()
+
+ emailer = Emailer()
+ for user in revision.contributors.all():
+ emailer.send_mail([user.email], 'Action required: Budget returned for re-drafting: {}'.format(revision.name), 'sstreasury/email/returned_committee.md', {'revision': revision})
+
return redirect(reverse('budget_view', kwargs={'id': budget.id}))