Skip to content

Commit

Permalink
allow site admins to force completion of in-progress projects
Browse files Browse the repository at this point in the history
* the "finish project" link/button is made visible to site admins on the
info pages of in-progress projects -- (projects which are not yet in the
QA stage and therefore not otherwise available to be marked complete).
** icon and label made to reflect that this action skips a step

* the "finish project" confirmation page is made to reflect when a
project is still in progress to warn unwitting admins

* the associated view/controller is updated to permit this action by
site admins
** (in fact, this view previously checked only for the user permission
-- not for project status -- and as such this was always available, and
to everyone with the project permission, who might have thought to try
this URL path. the view now further confirms that either the project is
in the QA state, or that both the project is in-progress and the request
is made by a site admin.)

resolves #66
  • Loading branch information
jesteria committed Feb 11, 2021
1 parent 931c43e commit 8a4e693
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 32 deletions.
11 changes: 11 additions & 0 deletions src/marketplace/templates/marketplace/proj_finish.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
{% extends 'marketplace/proj.html' %}

{% block tabcontents %}
{% if not project.is_waiting_review_status %}
<div class="section-header-primary alert alert-warning px-3" role="alert">
<i class="fas fa-exclamation-circle"></i>
This project is <em>not</em> in the final QA stage, and it is still considered <strong>in progress</strong>.
</div>
{% endif %}

<form id="finishproject">
<h4 class="section-header">Finish project</h4>

Expand All @@ -20,7 +27,11 @@ <h4 class="section-header">Finish project</h4>
</button>
<a class="btn btn-outline-primary" href="{% url 'marketplace:proj_info' project.id %}">
<i class="material-icons" style="vertical-align: middle">close</i>
{% if project.is_waiting_review_status %}
No, keep this project in QA
{% else %}
No, keep this project in progress
{% endif %}
</a>
</form>
{% endblock %}
13 changes: 6 additions & 7 deletions src/marketplace/templates/marketplace/proj_info.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{% extends "marketplace/proj.html" %}

{% block tabcontents %}

{% load markdown_deux_tags %}
{% load markdown_deux_tags rules %}

{% block tabcontents %}
<div class="row mt-5 mb-5">
<div class="col-lg-8">
<h4 class="section-header">Background and Motivation</h4>
Expand Down Expand Up @@ -37,7 +36,6 @@ <h4 class="section-header">Internal People Available During the Project</h4>
</button>
</form>
{% endif %}
{% load rules %}
{% has_perm 'project.publish' user project as perm_publish %}
{% if perm_publish and project.is_draft_status %}
<a class="btn btn-success col-lg-12 mb-1"
Expand All @@ -48,11 +46,12 @@ <h4 class="section-header">Internal People Available During the Project</h4>
{% endif %}

{% has_perm 'project.approve_as_completed' user project as perm_approve %}
{% if perm_approve and project.is_waiting_review_status %}
{% has_perm 'user.is_site_staff' user as is_site_staff %}
{% if perm_approve and project.is_waiting_review_status or is_site_staff and project.is_in_progress_status %}
<a class="btn btn-success col-lg-12 mb-1"
href="{% url 'marketplace:proj_finish' project.id %}">
<i class="material-icons" style="vertical-align: middle">done_all</i>
Finish project
<i class="material-icons" style="vertical-align: middle">{{ project.is_waiting_review_status|yesno:'done_all,fast_forward' }}</i>
Finish project {% if project.is_in_progress_status %}(without review){% endif %}
</a>
{% endif %}

Expand Down
45 changes: 20 additions & 25 deletions src/marketplace/views/proj.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from django.contrib.auth import logout
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.db.models import Max, Min
from django.core.exceptions import PermissionDenied, ValidationError
from django.db.models import Count, Max, Min
from django.db.models.functions import ExtractYear
from django.forms import CharField, ModelForm, Textarea
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.views import generic
from django.views.decorators.http import require_GET
from django.views.decorators.http import require_GET, require_http_methods
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from rules.contrib.views import (
PermissionRequiredMixin, objectgetter, permission_required,
Expand Down Expand Up @@ -1150,30 +1150,25 @@ def publish_project_view(request, proj_pk):
raise Http404


@require_http_methods(['GET', 'POST'])
@permission_required('project.approve_as_completed', raise_exception=True, fn=objectgetter(Project, 'proj_pk'))
def finish_project_view(request, proj_pk):
project = get_project(request, proj_pk)
project = get_object_or_404(Project.objects.annotate(follower_count=Count('projectfollower')), pk=proj_pk)

if not project.is_waiting_review_status() and not (project.is_in_progress_status() and
marketplace.user.is_site_staff(request.user)):
raise PermissionDenied

if request.method == 'POST':
try:
ProjectService.finish_project(request.user, proj_pk, project)
return redirect('marketplace:proj_info', proj_pk=proj_pk)
except KeyError:
messages.error(request, 'There was an error while processing your request.')
return redirect('marketplace:proj_info', proj_pk=proj_pk)
elif request.method == 'GET':
pass
if project:
return render(request, 'marketplace/proj_finish.html',
add_project_common_context(
request,
project,
'info',
{
'breadcrumb': project_breadcrumb(project,
('Finish project', None)),
}))
else:
raise Http404
marketplace.project.finish_project(request.user, project)
return redirect('marketplace:proj_info', proj_pk=proj_pk)

return render(request,
'marketplace/proj_finish.html',
add_project_common_context(request, project, 'info', {
'breadcrumb': project_breadcrumb(project, ('Finish project', None)),
}))


@permission_required('project.task_edit', raise_exception=True, fn=objectgetter(Project, 'proj_pk'))
def toggle_task_accepting_volunteers_view(request, proj_pk, task_pk):
Expand Down

0 comments on commit 8a4e693

Please sign in to comment.