From d712a8547f22da658ef5e4cacd55bdaba79d2691 Mon Sep 17 00:00:00 2001 From: James Graham Date: Thu, 23 Jan 2020 13:31:58 +0000 Subject: [PATCH 1/3] Fix inability to submit Fund forms - fixes #575 --- lowfat/forms.py | 11 ++--------- lowfat/views.py | 6 ++++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lowfat/forms.py b/lowfat/forms.py index 263517d9..d01e304c 100644 --- a/lowfat/forms.py +++ b/lowfat/forms.py @@ -9,7 +9,6 @@ EmailField, FileField, Form, - HiddenInput, ModelForm, Select, SelectMultiple, @@ -287,6 +286,7 @@ class Meta: "added", "approved", "updated", + "approval_chain", ] labels = { @@ -323,7 +323,6 @@ class Meta: usel10n=True, bootstrap_version=3 ), - 'approval_chain': HiddenInput, } @@ -441,9 +440,6 @@ def __init__(self, *args, **kwargs): self.fields['focus'].widget.choices.insert(0, ('', '---------')) self.fields['focus'].initial = '' - # For non-public funds use fellows approval chain - self.fields['approval_chain'].initial = ApprovalChain.FELLOWS - class FundPublicForm(GarlicForm): forenames = CharField( @@ -504,6 +500,7 @@ class Meta: "added", "approved", "updated", + "approval_chain", ] labels = { @@ -539,7 +536,6 @@ class Meta: usel10n=True, bootstrap_version=3 ), - 'approval_chain': HiddenInput, } @@ -656,9 +652,6 @@ def __init__(self, *args, **kwargs): self.fields['focus'].widget.choices.insert(0, ('', '---------')) self.fields['focus'].initial = '' - # For public funds use onetime request approval chain - self.fields['approval_chain'].initial = ApprovalChain.ONE_TIME - class FundGDPRForm(GarlicForm): class Meta: diff --git a/lowfat/views.py b/lowfat/views.py index a96da8ca..7bac1080 100644 --- a/lowfat/views.py +++ b/lowfat/views.py @@ -459,6 +459,9 @@ def fund_form(request, **kargs): # pylint: disable=too-many-branches,too-many-s if request.POST: # Handle submission if formset.is_valid(): + # Use Fellows approval chain for requests using this form + formset.instance.approval_chain = ApprovalChain.FELLOWS + fund = formset.save() messages.success(request, 'Funding request saved.') if not formset.cleaned_data["not_send_email_field"]: @@ -518,6 +521,9 @@ def fund_form_public(request): ) if request.POST and formset.is_valid(): + # Use One-Time approval chain for requests using this form + formset.instance.approval_chain = ApprovalChain.ONE_TIME + # Handle submission username = "{}.{}".format( formset.cleaned_data["forenames"].lower(), From 8a7a9f65f90077c4bd752cb6d6de4b17b8bc8e6b Mon Sep 17 00:00:00 2001 From: James Graham Date: Thu, 23 Jan 2020 14:26:04 +0000 Subject: [PATCH 2/3] Use FUND_STATUS_APPROVED_SET instead of "A" and "AM" - should fix #572 --- lowfat/forms.py | 8 ++--- lowfat/management/commands/fixstatus.py | 43 ++++++++++++------------- lowfat/models.py | 32 ++++++++++-------- lowfat/templates/lowfat/funds.html | 4 +-- lowfat/views.py | 30 +++++++++-------- 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/lowfat/forms.py b/lowfat/forms.py index d01e304c..c29cb0ad 100644 --- a/lowfat/forms.py +++ b/lowfat/forms.py @@ -874,7 +874,7 @@ def __init__(self, *args, **kwargs): if "initial" in kwargs and "fund" in kwargs["initial"]: self.fields['fund'].queryset = Fund.objects.filter(id=kwargs["initial"]["fund"].id) else: - self.fields['fund'].queryset = Fund.objects.filter(status__in=['A']) + self.fields['fund'].queryset = Fund.objects.filter(status__in=FUND_STATUS_APPROVED_SET) class ExpenseShortlistedForm(GarlicForm): class Meta: @@ -923,7 +923,7 @@ def __init__(self, *args, **kwargs): ) ) - self.fields['fund'].queryset = Fund.objects.filter(status__in={'A', 'M'}) + self.fields['fund'].queryset = Fund.objects.filter(status__in=FUND_STATUS_APPROVED_SET) class ExpenseReviewForm(GarlicForm): @@ -1055,10 +1055,10 @@ def __init__(self, *args, user=None, **kwargs): if "initial" in kwargs and "fund" in kwargs["initial"]: self.fields['fund'].queryset = Fund.objects.filter(id=kwargs["initial"]["fund"].id) else: - self.fields['fund'].queryset = Fund.objects.filter(status__in=['A']) + self.fields['fund'].queryset = Fund.objects.filter(status__in=FUND_STATUS_APPROVED_SET) if user: - self.fields['fund'].queryset = Fund.objects.filter(status__in=['A']) + self.fields['fund'].queryset = Fund.objects.filter(status__in=FUND_STATUS_APPROVED_SET) if self.is_staff: # Force staff to select one author diff --git a/lowfat/management/commands/fixstatus.py b/lowfat/management/commands/fixstatus.py index 2e4e2583..5be706f0 100644 --- a/lowfat/management/commands/fixstatus.py +++ b/lowfat/management/commands/fixstatus.py @@ -2,7 +2,7 @@ from django.core.management.base import BaseCommand -from lowfat.models import Fund, Expense +from lowfat.models import FUND_STATUS_APPROVED_SET, Fund, Expense class Command(BaseCommand): help = "Fix the status on the database." @@ -16,27 +16,26 @@ def handle(self, *args, **options): # Fund status # Move approved to archived - for fund in Fund.objects.all(): - if fund.status == "A": - day = datetime.timedelta(1) - if fund.added - datetime.datetime(2017, 12, 31) < day: - # Check for expenses - # Check for blog posts + for fund in Fund.objects.filter(status__in=FUND_STATUS_APPROVED_SET).all(): + day = datetime.timedelta(1) + if fund.added - datetime.datetime(2017, 12, 31) < day: + # Check for expenses + # Check for blog posts + print("Changing status for {}".format(fund)) + fund.status = "F" + fund.save() + else: + can_be_archive = True + expenses = Expense.objects.filter( + fund=fund, + ) + if not expenses: + can_be_archive = False + for expense in expenses: + if expense.status in ["S", "C"]: + can_be_archive = False + break + if can_be_archive: print("Changing status for {}".format(fund)) fund.status = "F" fund.save() - else: - can_be_archive = True - expenses = Expense.objects.filter( - fund=fund, - ) - if not expenses: - can_be_archive = False - for expense in expenses: - if expense.status in ["S", "C"]: - can_be_archive = False - break - if can_be_archive: - print("Changing status for {}".format(fund)) - fund.status = "F" - fund.save() diff --git a/lowfat/models.py b/lowfat/models.py index 09c9f253..62f76740 100644 --- a/lowfat/models.py +++ b/lowfat/models.py @@ -88,6 +88,12 @@ class TagMeta: ('X', 'Remove'), # When the fellow decided to remove their request. ) +#: Set of statuses which constitute an approved fund +FUND_STATUS_APPROVED_SET = { + 'A', + 'M', +} + FUND_STATUS_LONG_DESCRIPTION = { 'U': "We didn't start to process your request yet.", 'P': "One of your staffs is reviewing your request. You should have our reply soon.", @@ -521,7 +527,7 @@ def fullname_link(self): ) def claimantship_available(self): - """Return the remain claimantship grant.""" + """Return the remaining claimantship grant.""" money_available = 0 if self.inauguration_grant_expiration > date.today(): money_available = self.claimantship_grant - self.claimantship_committed() - self.claimantship_spent() @@ -529,7 +535,7 @@ def claimantship_available(self): return money_available def claimantship_passed(self): - """Return the ammount alread spent from the claimantship grant.""" + """Return the amount already spent from the claimantship grant.""" money_passed = 0 if self.inauguration_grant_expiration < date.today(): money_passed = self.claimantship_grant - self.claimantship_committed() - self.claimantship_spent() @@ -537,10 +543,10 @@ def claimantship_passed(self): return money_passed def claimantship_committed(self): - """Return the ammount committed from the claimantship grant.""" + """Return the amount committed from the claimantship grant.""" this_claimant_funds = Fund.objects.filter( claimant=self, - status__in=['A'], + status__in=FUND_STATUS_APPROVED_SET, grant_heading="F" ) @@ -548,16 +554,16 @@ def claimantship_committed(self): for fund in this_claimant_funds: spent_from_committed += sum([expense.amount_claimed for expense in Expense.objects.filter( fund=fund, - status__in=['A', 'F'] + status__in=['A', 'M', 'F'] )]) return sum([fund.budget_approved for fund in this_claimant_funds]) - spent_from_committed def claimantship_spent(self): - """Return the ammount alread spent from the claimantship grant.""" + """Return the amount already spent from the claimantship grant.""" this_claimant_expenses = Expense.objects.filter( fund__claimant=self, - status__in=['A', 'F'], + status__in=['A', 'M', 'F'], grant_heading="F" ) @@ -746,7 +752,7 @@ def save(self, *args, **kwargs): # pylint: disable=arguments-differ else: self.grant_heading = "C" - if self.status == "A": + if self.status in FUND_STATUS_APPROVED_SET: self.approved = datetime.now() if self.required_blog_posts is None: @@ -797,22 +803,22 @@ def budget_total(self): ) def expenses_claimed(self): - """Return the total ammount of expenses claimant.""" + """Return the total amount of expenses claimant.""" this_fund_expenses = Expense.objects.filter( fund=self, - status__in=["S", "C", "A"] + status__in=["S", "C", "A", "M"] ) return sum([expense.amount_claimed for expense in this_fund_expenses]) def expenses_claimed_left(self): - """Return the total ammount left to claimant.""" + """Return the total amount left to claimant.""" return self.budget_total() - self.expenses_claimed() def expenses_authorized_for_payment(self): - """Return the total ammount of expenses authorized_for_payment.""" + """Return the total amount of expenses authorized_for_payment.""" this_fund_expenses = Expense.objects.filter( fund=self, - status__in=["A"] + status__in=FUND_STATUS_APPROVED_SET ) return sum([expense.amount_authorized_for_payment for expense in this_fund_expenses]) diff --git a/lowfat/templates/lowfat/funds.html b/lowfat/templates/lowfat/funds.html index 7d8166b8..dd5d25c8 100644 --- a/lowfat/templates/lowfat/funds.html +++ b/lowfat/templates/lowfat/funds.html @@ -1,13 +1,13 @@ {% if user.is_staff %}