diff --git a/coldfront/core/grant/forms.py b/coldfront/core/grant/forms.py index 6f5679584..c2b3719c2 100644 --- a/coldfront/core/grant/forms.py +++ b/coldfront/core/grant/forms.py @@ -28,3 +28,25 @@ class GrantDeleteForm(forms.Form): max_length=30, required=False, disabled=True) grant_end = forms.CharField(max_length=150, required=False, disabled=True) selected = forms.BooleanField(initial=False, required=False) + + +class GrantDownloadForm(forms.Form): + pk = forms.IntegerField(required=False, disabled=True) + title = forms.CharField(required=False, disabled=True) + project_pk = forms.IntegerField(required=False, disabled=True) + pi_first_name = forms.CharField(required=False, disabled=True) + pi_last_name = forms.CharField(required=False, disabled=True) + role = forms.CharField(required=False, disabled=True) + grant_pi = forms.CharField(required=False, disabled=True) + total_amount_awarded = forms.FloatField(required=False, disabled=True) + funding_agency = forms.CharField(required=False, disabled=True) + grant_number = forms.CharField(required=False, disabled=True) + grant_start = forms.DateField(required=False, disabled=True) + grant_end = forms.DateField(required=False, disabled=True) + percent_credit = forms.FloatField(required=False, disabled=True) + direct_funding = forms.FloatField(required=False, disabled=True) + selected = forms.BooleanField(initial=False, required=False) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['pk'].widget = forms.HiddenInput() diff --git a/coldfront/core/grant/templates/grant/grant_report_list.html b/coldfront/core/grant/templates/grant/grant_report_list.html index 51ab402c1..10f915226 100644 --- a/coldfront/core/grant/templates/grant/grant_report_list.html +++ b/coldfront/core/grant/templates/grant/grant_report_list.html @@ -14,14 +14,17 @@

Grants

- Export to CSV +
- {% if grant_list %} + {% if formset %} +
+ {% csrf_token %}
+ @@ -36,24 +39,27 @@

Grants

- {% for grant in grant_list %} + {% for form in formset %} - - - - - - - - - - - + + + + + + + + + + + + {% endfor %}
Grant Title Project PI Faculty Role
{{ grant.title }}{{ grant.project.pi.first_name }} {{ grant.project.pi.last_name }}{{ grant.role }}{{ grant.grant_pi }}{{ grant.total_amount_awarded|intcomma }}{{ grant.funding_agency }}{{ grant.grant_number }}{{ grant.grant_start|date:"M. d, Y" }}{{ grant.grant_end|date:"M. d, Y" }}{{ grant.percent_credit }}{{ grant.direct_funding|intcomma }}{{ form.selected }}{{ form.title.value }}{{ form.pi_first_name.value }} {{ form.pi_last_name.value }}{{ form.role.value }}{{ form.grant_pi.value }}{{ form.total_amount_awarded.value|intcomma }}{{ form.funding_agency.value }}{{ form.grant_number.value }}{{ form.grant_start.value|date:"M. d, Y" }}{{ form.grant_end.value|date:"M. d, Y" }}{{ form.percent_credit.value }}{{ form.direct_funding.value|intcomma }}
+ {{ formset.management_form }} +
{% else %} {% endif %} @@ -70,8 +76,21 @@

Grants

{% endblock %} diff --git a/coldfront/core/grant/views.py b/coldfront/core/grant/views.py index 17a95e684..72ac345ee 100644 --- a/coldfront/core/grant/views.py +++ b/coldfront/core/grant/views.py @@ -11,7 +11,7 @@ from django.views.generic.edit import CreateView, UpdateView from coldfront.core.utils.common import Echo -from coldfront.core.grant.forms import GrantDeleteForm, GrantForm +from coldfront.core.grant.forms import GrantDeleteForm, GrantDownloadForm, GrantForm from coldfront.core.grant.models import (Grant, GrantFundingAgency, GrantStatusChoice) from coldfront.core.project.models import Project @@ -182,9 +182,7 @@ def get_success_url(self): class GrantReportView(LoginRequiredMixin, UserPassesTestMixin, ListView): - model = Grant template_name = 'grant/grant_report_list.html' - context_object_name = 'grant_list' def test_func(self): """ UserPassesTestMixin Tests""" @@ -197,6 +195,119 @@ def test_func(self): messages.error(self.request, 'You do not have permission to view all grants.') + def get_grants(self): + grants = Grant.objects.prefetch_related( + 'project', 'project__pi').all().order_by('-total_amount_awarded') + grants= [ + + {'pk': grant.pk, + 'title': grant.title, + 'project_pk': grant.project.pk, + 'pi_first_name': grant.project.pi.first_name, + 'pi_last_name':grant.project.pi.last_name, + 'role': grant.role, + 'grant_pi': grant.grant_pi, + 'total_amount_awarded': grant.total_amount_awarded, + 'funding_agency': grant.funding_agency, + 'grant_number': grant.grant_number, + 'grant_start': grant.grant_start, + 'grant_end': grant.grant_end, + 'percent_credit': grant.percent_credit, + 'direct_funding': grant.direct_funding, + } + for grant in grants + ] + + return grants + + + def get(self, request, *args, **kwargs): + context = {} + grants = self.get_grants() + + if grants: + formset = formset_factory(GrantDownloadForm, max_num=len(grants)) + formset = formset(initial=grants, prefix='grantdownloadform') + context['formset'] = formset + return render(request, self.template_name, context) + + + def post(self, request, *args, **kwargs): + grants = self.get_grants() + + formset = formset_factory(GrantDownloadForm, max_num=len(grants)) + formset = formset(request.POST, initial=grants, prefix='grantdownloadform') + + header = [ + 'Grant Title', + 'Project PI', + 'Faculty Role', + 'Grant PI', + 'Total Amount Awarded', + 'Funding Agency', + 'Grant Number', + 'Start Date', + 'End Date', + 'Percent Credit', + 'Direct Funding', + ] + rows = [] + grants_selected_count = 0 + + if formset.is_valid(): + for form in formset: + form_data = form.cleaned_data + if form_data['selected']: + grant = get_object_or_404(Grant, pk=form_data['pk']) + + row = [ + grant.title, + ' '.join((grant.project.pi.first_name, grant.project.pi.last_name)), + grant.role, + grant.grant_pi_full_name, + grant.total_amount_awarded, + grant.funding_agency, + grant.grant_number, + grant.grant_start, + grant.grant_end, + grant.percent_credit, + grant.direct_funding, + ] + + rows.append(row) + grants_selected_count += 1 + + if grants_selected_count == 0: + grants = Grant.objects.prefetch_related('project', 'project__pi').all().order_by('-total_amount_awarded') + for grant in grants: + row = [ + grant.title, + ' '.join((grant.project.pi.first_name, grant.project.pi.last_name)), + grant.role, + grant.grant_pi_full_name, + grant.total_amount_awarded, + grant.funding_agency, + grant.grant_number, + grant.grant_start, + grant.grant_end, + grant.percent_credit, + grant.direct_funding, + ] + rows.append(row) + + rows.insert(0, header) + pseudo_buffer = Echo() + writer = csv.writer(pseudo_buffer) + response = StreamingHttpResponse((writer.writerow(row) for row in rows), + content_type="text/csv") + response['Content-Disposition'] = 'attachment; filename="grants.csv"' + return response + else: + for error in formset.errors: + messages.error(request, error) + return HttpResponseRedirect(reverse('grant-report')) + + class GrantDownloadView(LoginRequiredMixin, UserPassesTestMixin, View): login_url = "/" diff --git a/coldfront/core/resource/admin.py b/coldfront/core/resource/admin.py index 2b3ab34ae..11a1f3cf8 100644 --- a/coldfront/core/resource/admin.py +++ b/coldfront/core/resource/admin.py @@ -53,6 +53,7 @@ class ResourceAdmin(SimpleHistoryAdmin): list_filter = ('resource_type__name', 'is_allocatable', 'is_available', 'is_public', 'requires_payment' ) inlines = [ResourceAttributeInline, ] filter_horizontal = ['allowed_groups', 'allowed_users', 'linked_resources', ] + save_as = True def resource_type_name(self, obj): return obj.resource_type.name