Added basic review functionality for club applications.
authorLennard de Rijk <ljvderijk@gmail.com>
Sat, 10 Jan 2009 14:44:04 +0000
changeset 797 0bc3f950d7cf
parent 796 126a1ef235ec
child 798 bd655740c03f
Added basic review functionality for club applications. The access rights are open for discussion. The review page uses GET data to determine the decision made by the user. For convenience the Review Club Applications button directs you to a multi-list view so you can see the state of different applications. The review state will reset whenever the application has been changed using the edit form. Patch by: Lennard de Rijk
app/soc/templates/soc/club_app/review.html
app/soc/views/helper/redirects.py
app/soc/views/models/club_app.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/club_app/review.html	Sat Jan 10 14:44:04 2009 +0000
@@ -0,0 +1,48 @@
+{% extends "soc/base.html" %}
+{% comment %}
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+{% load forms_helpers %}
+
+{% block header_title %}
+{{ page_name }} for {{ entity.name }}
+{% endblock %}
+
+{% block body %}
+<p>
+ <table>
+  {% readonly_field_as_twoline_table_row entity.fields.name.label entity.name %}
+  {% readonly_field_as_twoline_table_row entity.fields.applicant.label entity.applicant.link_id %}
+  {% readonly_field_as_twoline_table_row entity.fields.home_page.label entity.home_page %}
+  {% readonly_field_as_twoline_table_row entity.fields.email.label entity.email %}
+  {% readonly_field_as_twoline_table_row entity.fields.description.label entity.description %}
+  {% readonly_field_as_twoline_table_row entity.fields.why_applying.label entity.why_applying %}
+  {% readonly_field_as_twoline_table_row entity.fields.pub_mailing_list.label entity.pub_mailing_list %}
+  {% readonly_field_as_twoline_table_row entity.fields.irc_channel.label entity.irc_channel %}
+  {% readonly_field_as_twoline_table_row entity.fields.backup_admin.label entity.backup_admin.link_id %}
+  {% readonly_field_as_twoline_table_row entity.fields.member_criteria.label entity.member_criteria %}
+  {% readonly_field_as_twoline_table_row entity.fields.reviewed.label entity.reviewed %}
+  {% readonly_field_as_twoline_table_row entity.fields.accepted.label entity.accepted %}
+  {% readonly_field_as_twoline_table_row entity.fields.application_completed.label entity.application_completed %}
+ </table>
+</p>
+
+<tr>
+  <td>
+    <input type="button" onclick="location.href='/{{ entity_type_url|lower }}/review/{{ entity.link_id }}?accepted=true'" value="Accept"/>
+    <input type="button" onclick="location.href='/{{ entity_type_url|lower }}/review/{{ entity.link_id }}?accepted=false'" value="Deny"/>
+    <input type="button" onclick="location.href='/{{ entity_type_url|lower }}/delete/{{ entity.link_id }}'" value="Delete"/>
+  </td>
+</tr>
+</table>
+{% endblock %}
--- a/app/soc/views/helper/redirects.py	Sat Jan 10 14:14:38 2009 +0000
+++ b/app/soc/views/helper/redirects.py	Sat Jan 10 14:44:04 2009 +0000
@@ -56,6 +56,13 @@
 
   return '/%s/show/%s' % (
       params['url_name'], entity.key().name())
+  
+def getReviewRedirect(entity, params):
+  """Returns the redirect to review the specified entity
+  """
+  
+  return '/%s/review/%s' % (
+      params['url_name'], entity.link_id)
 
 
 def getCreateRequestRedirect(entity, params):
--- a/app/soc/views/models/club_app.py	Sat Jan 10 14:14:38 2009 +0000
+++ b/app/soc/views/models/club_app.py	Sat Jan 10 14:44:04 2009 +0000
@@ -19,26 +19,29 @@
 
 __authors__ = [
     '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+    '"Lennard de Rijk" <ljvderijk@gmail.com>',
   ]
 
 
 from django import forms
 from django.utils.translation import ugettext_lazy
 
-from soc.models import group_app as group_app_model
 from soc.logic import accounts
 from soc.logic import cleaning
 from soc.logic import dicts
 from soc.logic.models import user as user_logic
+from soc.models import group_app as group_app_model
 from soc.views import helper
+from soc.views import out_of_band
+from soc.views.helper import access
+from soc.views.helper import redirects
 from soc.views.models import group_app
-from soc.views.helper import access
 
 import soc.logic.dicts
 
 
 class View(group_app.View):
-  """View methods for the Sponsor model.
+  """View methods for the Club Application model.
   """
 
   def __init__(self, params=None):
@@ -54,6 +57,8 @@
     rights['delete'] = [access.checkIsMyApplication]
     rights['edit'] = [access.checkIsMyApplication]
     rights['list'] = [access.checkIsUser]
+    rights['public'] = [access.checkIsMyApplication]
+    rights['review'] = [access.checkIsDeveloper]
 
     new_params = {}
 
@@ -62,20 +67,36 @@
     new_params['create_template'] = 'soc/models/twoline_edit.html'
     new_params['edit_template'] = 'soc/models/twoline_edit.html'
 
-    new_params['extra_dynaexclude'] = ['applicant', 'backup_admin']
+    new_params['extra_dynaexclude'] = ['applicant', 'backup_admin',
+        'reviewed', 'accepted', 'application_completed']
     new_params['create_extra_dynafields'] = {
         'backup_admin_link_id': forms.CharField(
               label=group_app_model.GroupApplication.backup_admin.verbose_name
               ),
         'clean_backup_admin_link_id': cleaning.clean_existing_user('backup_admin_link_id'),
         }
-
+    
+    patterns = [(r'^%(url_name)s/(?P<access_type>review)$',
+        'soc.views.models.%(module_name)s.showReviewOverview',
+        'Review %(name_plural)s'),
+        (r'^%(url_name)s/(?P<access_type>review)/%(lnp)s$',
+          'soc.views.models.%(module_name)s.review',
+          'Review %(name_short)s')]
+    
+    new_params['extra_django_patterns'] = patterns
+    
     new_params['name'] = "Club Application"
     new_params['name_short'] = "Club Application"
-    new_params['name_plural'] = "Club Application"
+    new_params['name_plural'] = "Club Applications"
     new_params['url_name'] = "club_app"
     new_params['module_name'] = "club_app"
 
+    new_params['sidebar_additional'] = [
+        ('/%(url_name)s/review' % new_params,
+         'Review %(name_plural)s' % new_params, 'review')]
+    
+    new_params['review_template'] = 'soc/club_app/review.html'
+
     params = dicts.merge(params, new_params)
 
     super(View, self).__init__(params=params)
@@ -126,8 +147,132 @@
 
     if not entity:
       fields['applicant'] = user_logic.logic.getForCurrentAccount()
+      
+    # the application has either been created or edited so
+    # the review status needs to be set accordingly
+    fields['reviewed'] = False
+    fields['accepted'] = False
+      
+  def _public(self, request, entity, context):
+    """See base._public().
+    """
+    
+    context['entity_type_url'] = self._params['url_name']
 
 
+  def review(self, request, access_type,
+             page_name=None, params=None, **kwargs):
+    """Handles the view containing the review of an application.
+    
+    accepted (true or false) in the GET data will mark 
+    the application accordingly. 
+    
+    
+    For params see base.View.public().
+    """
+    
+    params = dicts.merge(params, self._params)
+    
+    try:
+      access.checkAccess(access_type, request, rights=params['rights'])
+    except out_of_band.Error, error:
+      return helper.responses.errorResponse(error, request)
+    
+    # create default template context for use with any templates
+    context = helper.responses.getUniversalContext(request)
+    context['page_name'] = page_name
+    entity = None
+
+    try:
+      key_fields = self._logic.getKeyFieldsFromDict(kwargs)
+      entity = self._logic.getIfFields(key_fields)
+    except out_of_band.Error, error:
+      return helper.responses.errorResponse(
+          error, request, template=params['error_public'], context=context)
+    
+    get_dict = request.GET
+    
+    # check to see if we can make a decision for this application
+    if 'accepted' in get_dict.keys():
+      accepted_value = get_dict['accepted']
+      
+      fields = {'reviewed' : False}
+      
+      if accepted_value == 'true':
+        # the application has been accepted
+        fields['accepted'] = True
+        fields['reviewed'] = True
+      elif accepted_value == 'false':
+        # the application has been denied
+        fields['accepted'] = False
+        fields['reviewed'] = True
+      
+      if fields['reviewed']: 
+        # the application has either been denied or accepted
+        # mark it as reviewed and update accordingly
+        application = self._logic.getFromFields(link_id=kwargs['link_id'])
+        self._logic.updateModelProperties(application, fields)
+        
+        return self.showUnhandledApplications(request, access_type, 
+            page_name=page_name, params=params, **kwargs)
+
+    # the application has nog been reviewed so show the information
+    # using the appropriate review template
+    params['public_template'] = params['review_template']
+
+    return super(View, self).public(request, access_type,
+        page_name=page_name, params=params, **kwargs)
+
+
+  def showReviewOverview(self, request, access_type,
+             page_name=None, params=None, **kwargs):
+    """Displays multiple lists of applications that are in different
+    states of the application process.
+    """
+
+    params = dicts.merge(params, self._params)
+
+    # only select the requests that haven't been reviewed yet
+    filter = {'reviewed' : False}
+
+    ur_params = params.copy()
+    ur_params['list_description'] = ugettext_lazy('A list of all unhandled '
+        'applications.')
+    ur_params ['list_action'] = (redirects.getReviewRedirect, params)
+
+    ur_list = helper.lists.getListContent(
+        request, ur_params, filter, 0)
+
+    # only select the requests that haven't been turned into a group yet
+    filter = {'accepted' : True, 
+        'application_completed' : False}
+
+    uh_params = params.copy()
+    uh_params['list_description'] = ugettext_lazy('A list of all applications '
+        'that have been accepted but not turned into a Club yet')
+    uh_params ['list_action'] = (redirects.getReviewRedirect, params)
+
+    uh_list = helper.lists.getListContent(
+        request, uh_params, filter, 0)
+
+    #only select the requests the have been denied
+    filter = {'reviewed' : True,
+        'accepted' : False}
+    
+    den_params = params.copy()
+    den_params['list_description'] = ugettext_lazy('A list of all applications '
+        'that have been denied')
+    den_params ['list_action'] = (redirects.getReviewRedirect, params)
+    
+    den_list = helper.lists.getListContent(
+        request, den_params, filter, 0)
+    
+    # fill contents with all the needed lists
+    contents = [ur_list, uh_list, den_list]
+    
+    # call the _list method from base to display the list
+    return self._list(request, params, contents, page_name)
+
 view = View()
 
 create = view.create
@@ -135,3 +280,5 @@
 edit = view.edit
 list = view.list
 public = view.public
+review = view.review
+showReviewOverview = view.showReviewOverview