summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYingtong Li <runassudo@yingtongli.me>2020-07-15 16:42:03 +1000
committerYingtong Li <runassudo@yingtongli.me>2020-07-15 16:53:22 +1000
commit1344f612f8cb5b9c190ddf276557b8485d768ccc (patch)
treea50e55f49f13b7d2875e426a8dd31f0f3f1eedb0
parente7e39ef66f8cad2b668989dfb35bb6f1c0728a69 (diff)
Add withdrawn, cancelled budget states
-rw-r--r--sstreasury/jinja2/sstreasury/budget_view.html6
-rw-r--r--sstreasury/models.py22
-rw-r--r--sstreasury/views.py16
3 files changed, 35 insertions, 9 deletions
diff --git a/sstreasury/jinja2/sstreasury/budget_view.html b/sstreasury/jinja2/sstreasury/budget_view.html
index d4d37ea..432a11c 100644
--- a/sstreasury/jinja2/sstreasury/budget_view.html
+++ b/sstreasury/jinja2/sstreasury/budget_view.html
@@ -43,6 +43,9 @@
{% if revision.can_withdraw(request.user) %}
<button class="ui mini labeled basic negative icon button" data-action="Withdraw" style="margin-left: 1em;" onclick="return uiConfirm(this);"><i class="undo icon"></i> Withdraw</button>
{% endif %}
+ {% if revision.can_cancel(request.user) %}
+ <button class="ui mini labeled basic negative icon button" data-action="Cancel" style="margin-left: 1em;" onclick="return uiConfirm(this);"><i class="times circle outline icon"></i> Cancel</button>
+ {% endif %}
{% if revision.can_edit(request.user) %}
<a class="ui mini labeled right floated icon button" href="{{ url('budget_edit', kwargs={'id': revision.budget.id}) }}"><i class="edit icon"></i> Edit</a>
@@ -290,6 +293,9 @@
<div class="content" data-action="Withdraw">
<p>Are you sure you want to withdraw this budget from being considered for approval? The budget will be reverted to a draft.</p>
</div>
+ <div class="content" data-action="Cancel">
+ <p>Are you sure you want to cancel this budget?</p>
+ </div>
<div class="actions">
<div class="ui primary approve button">Continue</div>
<div class="ui cancel button">Cancel</div>
diff --git a/sstreasury/models.py b/sstreasury/models.py
index 87c82e5..6e2342b 100644
--- a/sstreasury/models.py
+++ b/sstreasury/models.py
@@ -44,11 +44,12 @@ class BudgetComment(models.Model):
class BudgetState(DescriptionEnum):
DRAFT = 10, 'Draft'
+ WITHDRAWN = 15, 'Withdrawn'
RESUBMIT = 20, 'Returned for redrafting'
AWAIT_REVIEW = 30, 'Awaiting Treasury review'
ENDORSED = 40, 'Endorsed by Treasury, awaiting committee approval'
APPROVED = 50, 'Approved'
- #CANCELLED = 60, 'Cancelled'
+ CANCELLED = 60, 'Cancelled'
class BudgetAction(DescriptionEnum):
CREATE = 5, 'Created'
@@ -121,7 +122,7 @@ class BudgetRevision(models.Model):
return True
if user.groups.filter(name='Treasury').exists():
return True
- if (self.state == BudgetState.AWAIT_REVIEW.value or self.state == BudgetState.ENDORSED.value or self.state == BudgetState.APPROVED.value) and user.groups.filter(name='Committee').exists():
+ if self.state in (BudgetState.AWAIT_REVIEW.value, BudgetState.ENDORSED.value, BudgetState.APPROVED.value) and user.groups.filter(name='Committee').exists():
return True
return False
@@ -136,7 +137,7 @@ class BudgetRevision(models.Model):
return False
# Only Treasurer or Secretary may edit if submitted
- if self.state != BudgetState.DRAFT.value and self.state != BudgetState.RESUBMIT.value:
+ if self.state not in (BudgetState.DRAFT.value, BudgetState.RESUBMIT.value, BudgetState.WITHDRAWN.value):
if user.groups.filter(name='Treasury').exists() or user.groups.filter(name='Secretary').exists():
return True
return False
@@ -155,7 +156,7 @@ class BudgetRevision(models.Model):
def can_submit(self, user):
if not self.can_edit(user):
return False
- if self.state == BudgetState.DRAFT.value or self.state == BudgetState.RESUBMIT.value:
+ if self.state in (BudgetState.DRAFT.value, BudgetState.RESUBMIT.value, BudgetState.WITHDRAWN.value):
return True
return False
@@ -165,7 +166,7 @@ class BudgetRevision(models.Model):
if user != self.author and user not in self.contributors.all() and not user.groups.filter(name='Treasury').exists():
return False
- if self.state == BudgetState.AWAIT_REVIEW.value or self.state == BudgetState.ENDORSED.value:
+ if self.state in (BudgetState.DRAFT.value, BudgetState.RESUBMIT.value, BudgetState.AWAIT_REVIEW.value, BudgetState.ENDORSED.value):
return True
return False
@@ -174,7 +175,7 @@ class BudgetRevision(models.Model):
return False
if not user.groups.filter(name='Treasury').exists():
return False
- if self.state == BudgetState.AWAIT_REVIEW.value or self.state == BudgetState.DRAFT.value or self.state == BudgetState.RESUBMIT.value:
+ if self.state in (BudgetState.AWAIT_REVIEW.value, BudgetState.DRAFT.value, BudgetState.RESUBMIT.value, BudgetState.WITHDRAWN.value):
return True
return False
@@ -196,6 +197,15 @@ class BudgetRevision(models.Model):
if self.state == BudgetState.APPROVED.value:
return False
return self.can_approve(user)
+
+ def can_cancel(self, user):
+ if not self.can_view(user):
+ return False
+ if not user.groups.filter(name='Secretary').exists() and not user.groups.filter(name='Treasury').exists():
+ return False
+ if self.state != BudgetState.APPROVED.value:
+ return False
+ return True
class ClaimState(DescriptionEnum):
DRAFT = 10, 'Draft'
diff --git a/sstreasury/views.py b/sstreasury/views.py
index 4cedc83..67b5a7d 100644
--- a/sstreasury/views.py
+++ b/sstreasury/views.py
@@ -211,6 +211,9 @@ def budget_list(request):
revision = budget.budgetrevision_set.reverse()[0]
state = models.BudgetState(revision.state)
+ if not revision.can_view(request.user):
+ continue
+
group = None
if request.user.groups.filter(name='Treasury').exists() and state == models.BudgetState.AWAIT_REVIEW:
@@ -226,8 +229,8 @@ def budget_list(request):
group = budgets_open
else:
group = budgets_closed
- elif request.user.groups.filter(name='Treasury').exists() or request.user.groups.filter(name='Secretary').exists() or request.user.groups.filter(name='Committee').exists():
- if state == models.BudgetState.APPROVED:
+ else:
+ if state in (models.BudgetState.APPROVED, models.BudgetState.WITHDRAWN, models.BudgetState.CANCELLED):
group = budgets_closed
else:
group = budgets_open
@@ -390,7 +393,7 @@ def budget_action(request, budget, revision):
raise PermissionDenied
with transaction.atomic():
- revision.update_state(request.user, models.BudgetState.DRAFT)
+ revision.update_state(request.user, models.BudgetState.WITHDRAWN)
if 'Endorse' in actions:
if not revision.can_endorse(request.user):
@@ -438,6 +441,13 @@ def budget_action(request, budget, revision):
for user in revision.contributors.all():
emailer.send_mail([user.email], 'Action required: Budget returned for re-drafting: {} (BU-{})'.format(revision.name, budget.id), 'sstreasury/email/budget_returned_committee.md', {'revision': revision})
+ if 'Cancel' in actions:
+ if not revision.can_cancel(request.user):
+ raise PermissionDenied
+
+ with transaction.atomic():
+ revision.update_state(request.user, models.BudgetState.CANCELLED)
+
return redirect(reverse('budget_view', kwargs={'id': budget.id}))
@login_required
Contact (issues, pull requests, etc.) at git@yingtongli.me. Generated by cgit.